This notebook complements the “Introduction to the Tidyverse” workshop which is part of the Machine Learning in R (winter term 2020/21). For the purpose of reproducibility, it contains all examples and use cases discussed in the workshop.

Package Management

#check if pacman is installed (install if evaluates to FALSE)
if (!require(pacman) == T) install.packages("pacman")
Lade n昼㸶tiges Paket: pacman
#load (or install if pacman cannot find an existing installation) the relevant packages
pacman::p_load(tidyverse, plotly, patchwork)
pacman::p_load_gh("allisonhorst/palmerpenguins")

palmerpenguins Data Set

penguins

magrittr: A Forward-Pipe Operator for R

mean(subset(penguins, year == 2007)$body_mass_g, na.rm = T)
[1] 4124.541
#alternatively:
peng_bmi_2007 <- subset(penguins, year == 2007)$body_mass_g
mean(peng_bmi_2007, na.rm = T)
[1] 4124.541
penguins %>% 
  subset(year == 2007) %>% 
  .$body_mass_g %>% 
  mean(na.rm = T)
[1] 4124.541

tibble: Simple Data Frames

tibble():

tibble::tibble(
  x = c("a", "b"),
  y = c(1, 2),
  z = c(T, F)
)

tribble():

tibble::tribble(
  ~x, ~y,  ~z,
  "a", 1,  T,
  "b", 2,  F
)

as_tibble():

df <- data.frame(
  x = c("a", "b"), y = c(1, 2), z = c(T, F)
)

tibble::as_tibble(df)

enframe():

c(x = "a", y = "b") %>%
  tibble::enframe(name = "x", value = "y")

readr: Read Rectangular Text Data

write_csv():

penguins %>% 
  write_csv(path = "./penguins.csv")

read_csv():

penguins <- readr::read_csv("./penguins.csv")
Parsed with column specification:
cols(
  species = col_character(),
  island = col_character(),
  bill_length_mm = col_double(),
  bill_depth_mm = col_double(),
  flipper_length_mm = col_double(),
  body_mass_g = col_double(),
  sex = col_character(),
  year = col_double()
)

read_csv() with explicit column specifications:

readr::read_csv(
  "./penguins.csv",
    col_types = cols(
      species = col_character(),
      year = col_datetime(format = "%Y"),
      island = col_skip()
    )
  )

read_csv() with changing the default for guess_max:

readr::read_csv(file = "./penguins.csv", guess_max = 1001)
Parsed with column specification:
cols(
  species = col_character(),
  island = col_character(),
  bill_length_mm = col_double(),
  bill_depth_mm = col_double(),
  flipper_length_mm = col_double(),
  body_mass_g = col_double(),
  sex = col_character(),
  year = col_double()
)

##tidyr: Tidy Messy Data

pivot_longer():

penguins_long <- penguins %>% 
  #create id column here to assign each observation a unique key
  mutate(id = dplyr::row_number(), .before = species) %>% 
  tidyr::pivot_longer(
    cols = contains("_mm"),
    names_to = "meas_type", values_to = "measurement"
  )

penguins_long

pivot_wider():

penguins_long %>% 
  tidyr::pivot_wider(
    names_from = "meas_type", values_from = "measurement"
  )

nest():

nested_penguins <- penguins %>% 
  tidyr::nest(
    nested_data = c(island, bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g, sex)
  )

nested_penguins

unnest():

nested_penguins %>% 
  unnest(col = nested_data)

unnest_wider() to unpack columns:

nested_penguins %>% 
  unnest_wider(col = nested_data)

unnest_longer() to unpack rows (here island):

nested_penguins %>% 
  unnest_wider(col = nested_data) %>% 
  unnest_longer(col = c(island))

unite():

united_penguins <- penguins %>% 
  tidyr::unite(col = "spec_gender", c(species, sex), sep = "_", remove = T)

united_penguins

separate():

united_penguins %>% 
  tidyr::separate(col = spec_gender, into = c("species", "sex"), sep = "_", remove = T)

complete() to make implicit NA explicit:

incompl_penguins <- tibble(
  species = c(rep("Adelie", 2), rep("Gentoo", 1), rep("Chinstrap", 1)),
  year = c(2007, 2008, 2008, 2007),
  value = c(rnorm(3, mean = 50, sd = 15), NA)
)

incompl_penguins
incompl_penguins %>% 
  tidyr::complete(
    species, year, fill = list(value = NA)
)

drop_na() to make explicit NA implicit:

incompl_penguins %>% 
  drop_na(value)

fill() to replace explicit NA with previous value:

incompl_penguins %>% 
  tidyr::fill(value, .direction = "down")

replace_na() to replace explicit NA with column mean:

incompl_penguins %>%
  tidyr::replace_na(replace = list(value = mean(.$value, na.rm = T)))

dplyr: A Grammar of Data Manipulation

filter() to filter for rows that fulfill condition:

penguins %>% 
  filter(species == "Adelie")
penguins %>% 
  filter(is.na(bill_length_mm) == T)
penguins %>% 
  filter(between(body_mass_g, 3800, 4000) & year < 2008)

slice() to pick rows based on location:

penguins %>% 
  slice(23:26)
penguins %>% 
  slice_head(n = 5)
penguins %>% 
  slice_sample(prop = 0.02)
penguins %>% 
  slice_min(flipper_length_mm, n = 5)

arrange() to change the order of rows:

penguins %>% 
  arrange(body_mass_g) %>% 
  slice_head(n = 3)
penguins %>% 
  arrange(desc(body_mass_g)) %>% 
  slice_head(n = 3)

select() to pick respectively drop certain columns:

penguins %>% 
  select(1:3)
penguins %>% 
  select(species, island, bill_length_mm)
penguins %>% 
  select(starts_with("s"))
penguins %>% 
  select(ends_with("mm"))
penguins %>% 
  select(contains("mm"))
penguins %>% 
  select(-contains("mm"))
penguins %>% 
  select(where(is.numeric)) %>%   #equivalent to select(where(~is.numeric(.)))
  select(where(~mean(., na.rm=T) > 1000))

rename() to change column names:

penguins %>% 
  rename(bmi = body_mass_g, gender = sex) %>% 
  colnames()
[1] "species"           "island"            "bill_length_mm"    "bill_depth_mm"    
[5] "flipper_length_mm" "bmi"               "gender"            "year"             
penguins %>% 
  rename_with(.fn = toupper, .cols = contains("mm")) %>% 
  colnames()
[1] "species"           "island"            "BILL_LENGTH_MM"    "BILL_DEPTH_MM"    
[5] "FLIPPER_LENGTH_MM" "body_mass_g"       "sex"               "year"             

relocate() to change the order of columns:

penguins %>% 
  relocate(species, .after = body_mass_g) %>%
  relocate(sex, .before = species) %>%
  relocate(island, .after = last_col())

mutate() to change the values of columns and/or create new columns:

penguins %>% 
  mutate(
    bm_kg = body_mass_g / 1000,
    .keep = "all",
    .after = body_mass_g)
penguins %>% 
  mutate(
    sex = case_when(
      sex == "male" ~ 1,
      sex == "female" ~ 0),
    .keep = "all")
penguins %>% 
  mutate(
    across(contains("mm"), ~ . / 1000),
    .keep = "all")

group_by() to group rows based on a set of columns:

penguins %>% 
  group_by(species)

summarise() to reduce a group into a single row:

penguins %>% 
  group_by(species) %>% #univariate
  summarise(count = n(), .groups = "drop")
penguins %>% 
  group_by(species, year) %>% #bivariate
  summarise(count = n(), .groups = "drop")
penguins %>% 
  group_by(species) %>%
  summarise(
    across(contains("mm"), ~mean(., na.rm = T), .names = "{.col}_avg"),
    .groups = "drop")
penguins %>% 
  group_by(species) %>% 
  group_by(year, .add = T) 
penguins %>% 
  group_by(species) %>%
  summarise(
    across(
      contains("mm"),
      list(avg = ~mean(., na.rm = T), sd = ~sd(., na.rm = T)),
      .names = "{.col}_{.fn}"),
    .groups = "drop")
penguins %>% 
  group_by(species) %>% 
  mutate(stand_bm = (body_mass_g - mean(body_mass_g, na.rm = TRUE)) / 
           sd(body_mass_g, na.rm = TRUE))
bm_breaks <- mean(penguins$body_mass_g, na.rm = T) -
  (-3:3) * sd(penguins$body_mass_g, na.rm = T)

penguins %>% 
  group_by(species, bm_cat = cut(body_mass_g, breaks = bm_breaks)) %>% 
  summarise(count = n(), .groups = "drop")
penguins %>% 
  group_by(species, island) %>% 
  filter(flipper_length_mm == max(flipper_length_mm, na.rm = T))
penguins %>% 
  group_by(species, year) %>% 
  nest

distinct() to select only unique rows:

penguins %>% 
  distinct(species, island)

pull() to extract single columns as vectors:

penguins %>% 
  pull(year) #equivalent to penguins$year
  [1] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
 [19] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
 [37] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2008 2008 2008 2008
 [55] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008
 [73] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008
 [91] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2009 2009 2009 2009 2009 2009 2009 2009
[109] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
[127] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
[145] 2009 2009 2009 2009 2009 2009 2009 2009 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
[163] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
[181] 2007 2007 2007 2007 2007 2007 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008
[199] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008
[217] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2009 2009
[235] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
[253] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
[271] 2009 2009 2009 2009 2009 2009 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
[289] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2008 2008 2008 2008
[307] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2009 2009 2009 2009
[325] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
[343] 2009 2009

if_else() to apply a vectorized if-else-statement

penguins %>% 
  select(species, island, body_mass_g) %>% 
  mutate(penguin_size = if_else(body_mass_g < 3500, "tiny penguin", "big penguin"))

lag() and lead() to shift column values by an offset n:

penguins %>% 
  select(species, body_mass_g) %>% 
  mutate(
    lagged_bm = lag(body_mass_g, n = 1),
    lead_bm = lead(body_mass_g, n = 2))

purrr: Functional Programming Tools

map() to apply a function to each element of a vector:

z_transform <- function(.x) {
  mean <- mean(.x, na.rm = T)
  sd <- sd(.x, na.rm = T)
  return( (.x - mean) / sd )
}

penguins %>% 
  select(contains("mm")) %>% 
  map(.x = ., .f = ~z_transform(.x))
$bill_length_mm
  [1] -0.88320467 -0.80993901 -0.66340769          NA -1.32279862 -0.84657184 -0.91983750
  [8] -0.86488825 -1.79902541 -0.35202864 -1.12131806 -1.12131806 -0.51687637 -0.97478674
 [15] -1.70744334 -1.34111504 -0.95647033 -0.26044656 -1.74407616  0.38062795 -1.12131806
 [22] -1.13963448 -1.46932994 -1.04805240 -0.93815391 -1.57922843 -0.60845845 -0.62677486
 [29] -1.10300165 -0.62677486 -0.80993901 -1.23121655 -0.80993901 -0.55350920 -1.37774787
 [36] -0.86488825 -0.93815391 -0.31539581 -1.15795089 -0.75498976 -1.35943145 -0.57182562
 [43] -1.45101353  0.03261607 -1.26784938 -0.79162259 -0.51687637 -1.17626731 -1.45101353
 [50] -0.29707939 -0.79162259 -0.70004052 -1.63417768 -0.35202864 -1.72575975 -0.46192713
 [57] -0.90152108 -0.60845845 -1.35943145 -1.15795089 -1.50596277 -0.48024354 -1.15795089
 [64] -0.51687637 -1.37774787 -0.42529430 -1.54259560 -0.51687637 -1.46932994 -0.38866147
 [71] -1.90892390 -0.77330618 -0.79162259  0.34399512 -1.54259560 -0.20549732 -0.55350920
 [78] -1.23121655 -1.41438070 -0.33371222 -1.70744334 -0.18718091 -1.32279862 -1.61586126
 [85] -1.21290014 -0.48024354 -1.39606428 -1.28616579 -1.02973599 -0.91983750 -1.50596277
 [92] -0.51687637 -1.81734182 -0.79162259 -1.41438070 -0.57182562 -1.06636882 -0.66340769
 [99] -1.98218956 -0.13223166 -1.63417768 -0.53519279 -1.13963448 -1.12131806 -1.10300165
[106] -0.77330618 -0.97478674 -1.04805240 -1.06636882 -0.13223166 -1.06636882  0.30736229
[113] -0.77330618 -0.31539581 -0.79162259 -0.22381374 -0.97478674 -1.21290014 -1.50596277
[120] -0.51687637 -1.41438070 -1.13963448 -0.68172411 -0.46192713 -1.59754485 -0.60845845
[127] -0.93815391 -0.44361071 -0.90152108  0.03261607 -0.99310316 -0.15054808 -1.30448221
[134] -1.17626731 -1.06636882 -0.51687637 -1.52427919 -0.68172411 -1.26784938 -0.77330618
[141] -0.68172411 -0.60845845 -2.16535371 -0.59014203 -1.21290014 -0.90152108 -0.86488825
[148] -1.34111504 -1.45101353 -1.12131806 -1.45101353 -0.44361071  0.39894437  1.11328455
[155]  0.87517115  1.11328455  0.67369059  0.47221003  0.27072946  0.50884286 -0.11391525
[162]  0.52715927 -0.55350920  0.93012040  0.28904588  0.82022191  0.34399512  0.98506964
[169] -0.35202864  0.96675323  0.41726078  0.87517115  1.14991738  0.21578022  0.47221003
[176]  0.43557720 -0.18718091  0.39894437  0.10588173  0.71032342  0.78358908  1.11328455
[183]  0.61874135 -0.20549732  0.21578022  2.87166037  0.94843681  0.82022191 -0.24213015
[190]  0.08756532  0.01429966  0.87517115 -0.22381374  1.04001889  0.25241305  1.04001889
[197]  1.20486662 -0.05896600  0.28904588  1.20486662  0.17914739  0.23409663  0.49052644
[204]  0.83853832  0.21578022  1.13160096  0.47221003  0.19746381 -0.02233317  0.28904588
[211] -0.13223166  1.18655021  0.25241305  0.41726078  0.32567871  1.90089038  0.34399512
[218]  1.07665172  0.41726078  1.02170247 -0.07728242  1.24149945  0.69200701  0.45389361
[225]  0.78358908  0.47221003  0.45389361  0.85685474  0.65537418  1.31476511  0.23409663
[232]  0.23409663  0.94843681  1.57119492  0.63705776  1.11328455  0.17914739  1.25981586
[239] -0.09559883  1.35139794  0.65537418  1.49792926  0.65537418  1.51624567  0.28904588
[246]  1.02170247  0.10588173  1.25981586  1.00338606  0.54547569  0.82022191  1.31476511
[253]  0.83853832  2.19395302  0.60042493  0.94843681  0.61874135  0.52715927 -0.40697788
[260]  1.73604265 -0.11391525  0.76527266  1.20486662  1.07665172 -0.07728242  1.38803077
[267]  0.41726078  2.04742170  0.10588173  0.89348757  0.60042493          NA  0.52715927
[274]  1.18655021  0.23409663  1.09496813  0.47221003  1.11328455  1.35139794  0.27072946
[281]  1.60782775  0.23409663  0.39894437  1.35139794  0.38062795  1.35139794  0.49052644
[288]  1.42466360  0.56379210  1.47961284  0.36231154  1.20486662  1.16823379  2.57859773
[295]  0.45389361  0.96675323 -0.27876298  0.83853832 -0.13223166  1.22318303  0.50884286
[302]  1.47961284  1.20486662  1.02170247  0.45389361  1.62614416 -0.55350920  1.88257397
[309] -0.26044656  1.29644869  1.05833530  0.65537418  0.67369059  1.47961284  0.54547569
[316]  1.75435906  0.93012040  0.41726078  1.27813228  0.28904588  1.27813228  1.25981586
[323]  1.13160096  0.93012040  1.38803077  1.07665172  0.76527266  1.36971435  0.32567871
[330]  1.24149945 -0.26044656  1.51624567  0.23409663  0.98506964  1.14991738  0.30736229
[337]  1.46129643  0.52715927  0.32567871  2.17563660 -0.07728242  1.04001889  1.25981586
[344]  1.14991738

$bill_depth_mm
  [1]  0.78430007  0.12600328  0.42983257          NA  1.08812936  1.74642615  0.32855614
  [8]  1.24004400  0.48047078  1.54387329 -0.02591137  0.07536506  0.22727971  2.05025544
 [15]  1.99961722  0.32855614  0.93621471  1.79706436  0.63238542  2.20217008  0.58174721
 [22]  0.78430007  1.03749114  0.48047078  0.02472685  0.88557650  0.73366185  0.37919435
 [29]  0.73366185  0.88557650 -0.22846423  0.48047078  0.32855614  0.88557650 -0.07654958
 [36]  1.99961722  1.44259686  0.68302364  1.08812936  0.98685293  0.42983257  0.63238542
 [43]  0.68302364  1.29068222 -0.12718780  0.83493828  0.93621471  0.88557650  0.37919435
 [50]  2.05025544  0.27791792  0.88557650  0.37919435  1.18940579  0.48047078  0.73366185
 [57]  0.17664149  0.83493828 -0.27910244  0.98685293 -0.12718780  1.99961722 -0.07654958
 [64]  0.53110900 -0.02591137  0.42983257 -0.48165530  0.98685293 -0.27910244  1.13876757
 [71]  0.93621471  0.63238542  0.02472685  0.88557650  0.17664149  0.68302364 -0.17782601
 [78]  1.13876757 -0.53229351  0.98685293  0.02472685  0.22727971  0.83493828  1.13876757
 [85]  0.32855614  1.59451151  1.18940579  0.73366185  1.03749114  0.83493828  0.42983257
 [92]  0.48047078 -0.02591137  0.48047078  0.07536506  0.88557650  0.73366185  0.68302364
 [99] -0.53229351  0.68302364  0.37919435  1.44259686 -0.58293173  1.44259686  0.73366185
[106]  0.88557650  0.02472685  1.44259686 -0.07654958  0.93621471 -0.32974066  1.59451151
[113]  0.27791792  1.18940579  1.79706436  0.58174721 -0.07654958  1.69578793 -0.07654958
[120]  0.73366185  0.02472685  1.34132043 -0.07654958  0.68302364 -0.63356994  0.93621471
[127]  0.22727971  0.58174721 -0.02591137  0.42983257  0.37919435  1.03749114  0.68302364
[134]  0.68302364  0.22727971  0.17664149  0.17664149  1.49323508 -0.32974066  0.37919435
[141] -0.02591137  0.02472685 -0.83612280 -0.07654958 -0.17782601  0.78430007  0.73366185
[148]  0.63238542  0.32855614  0.48047078 -0.02591137  0.68302364 -2.00080174 -0.43101709
[155] -1.54505781 -0.98803745 -1.34250495 -1.84888710 -1.29186674 -0.93739923 -1.89952531
[162] -0.88676102 -1.74761067 -0.53229351 -1.74761067 -1.29186674 -1.29186674 -0.73484637
[169] -1.84888710 -0.98803745 -1.34250495 -1.03867566 -1.44378138 -1.34250495 -1.34250495
[176] -0.68420816 -2.05143996 -1.03867566 -1.44378138 -1.08931388 -1.44378138 -0.93739923
[183] -0.93739923 -1.49441960 -1.34250495 -0.07654958 -1.19059031 -0.43101709 -1.74761067
[190]  0.07536506 -1.79824888 -0.73484637 -1.74761067 -0.58293173 -1.74761067 -1.08931388
[197] -0.63356994 -1.64633424 -1.64633424 -0.63356994 -1.95016353 -0.68420816 -1.49441960
[204] -1.54505781 -1.39314317 -1.08931388 -1.39314317 -0.88676102 -1.64633424 -1.08931388
[211] -1.34250495 -0.93739923 -1.69697245 -1.13995209 -1.64633424 -0.73484637 -1.49441960
[218] -0.17782601 -1.39314317 -0.48165530 -1.49441960 -1.08931388 -1.08931388 -0.78548459
[225] -0.78548459 -1.19059031 -1.08931388 -0.58293173 -1.49441960 -0.43101709 -1.69697245
[232] -0.38037887 -1.34250495 -0.78548459 -1.29186674 -0.63356994 -1.69697245  0.07536506
[239] -1.39314317 -1.49441960 -1.59569603 -0.07654958 -1.08931388 -0.02591137 -1.34250495
[246] -0.53229351 -1.24122852 -0.73484637 -0.68420816 -1.29186674 -1.39314317 -0.32974066
[253] -1.08931388 -0.07654958 -0.83612280 -1.08931388 -1.69697245 -0.53229351 -1.24122852
[260] -0.68420816 -1.59569603 -1.03867566 -0.98803745 -0.63356994 -0.98803745 -0.43101709
[267] -1.54505781 -0.58293173 -0.73484637 -0.48165530 -1.74761067          NA -1.44378138
[274] -0.73484637 -1.19059031 -0.53229351  0.37919435  1.18940579  1.03749114  0.78430007
[281]  1.34132043  0.32855614  0.53110900  0.53110900  0.88557650  1.39195865  0.32855614
[288]  1.59451151  0.07536506  0.48047078 -0.02591137  1.24004400  1.44259686  0.32855614
[295]  0.73366185  0.53110900  0.07536506  0.17664149 -0.27910244  1.13876757  0.37919435
[302]  0.93621471  0.63238542  0.93621471  0.32855614  1.44259686 -0.27910244  1.84770258
[309] -0.22846423  0.83493828  0.73366185 -0.17782601  0.58174721  1.79706436 -0.27910244
[316]  1.39195865  1.18940579  0.17664149  0.98685293 -0.07654958  0.37919435  0.68302364
[323]  0.37919435  1.24004400  0.78430007  0.07536506 -0.38037887  0.93621471  0.07536506
[330]  1.29068222  0.07536506  0.83493828 -0.27910244  1.39195865  0.83493828  1.13876757
[337]  1.18940579 -0.32974066 -0.07654958  1.34132043  0.48047078  0.53110900  0.93621471
[344]  0.78430007

$flipper_length_mm
  [1] -1.416271525 -1.060696087 -0.420660299           NA -0.562890474 -0.776235737 -1.416271525
  [8] -0.420660299 -0.562890474 -0.776235737 -1.060696087 -1.487386613 -1.345156438 -0.705120649
 [15] -0.207315036 -1.131811175 -0.420660299 -0.278430124 -1.202926262 -0.491775386 -1.914077138
 [22] -1.487386613 -0.847350824 -1.131811175 -1.487386613 -0.989581000 -1.274041350 -0.989581000
 [29] -2.056307313 -1.487386613 -1.629616788 -1.629616788 -0.918465912 -1.202926262 -0.420660299
 [36] -0.349545211 -0.776235737 -1.487386613 -1.416271525 -1.202926262 -1.345156438 -0.420660299
 [43] -1.060696087 -0.349545211 -1.131811175 -0.776235737 -1.345156438 -1.558501700 -0.776235737
 [50] -0.705120649 -1.060696087 -0.918465912 -0.776235737 -0.065084861 -0.989581000 -0.705120649
 [57] -1.060696087 -0.562890474 -1.416271525 -0.491775386 -1.131811175 -0.420660299 -1.131811175
 [64] -0.634005562 -1.202926262 -0.634005562 -0.420660299 -0.918465912 -0.776235737 -0.207315036
 [71] -0.776235737 -0.776235737 -0.349545211 -0.278430124 -0.776235737 -0.420660299 -0.705120649
 [78] -1.202926262 -0.989581000 -0.420660299 -0.847350824 -0.349545211 -0.989581000 -0.562890474
 [85] -0.705120649 -0.491775386 -0.776235737 -0.847350824 -0.847350824 -0.776235737  0.077145314
 [92]  0.290490577 -1.131811175 -1.060696087 -0.989581000  0.503835840 -0.776235737 -0.349545211
 [99] -1.629616788 -0.634005562 -0.634005562  0.148260402 -1.274041350 -0.776235737 -0.562890474
[106] -1.202926262 -0.136199948 -0.776235737 -1.416271525 -0.278430124 -0.207315036 -0.705120649
[113] -0.562890474 -0.278430124 -0.705120649 -0.349545211 -0.918465912 -0.136199948 -0.847350824
[120] -0.847350824 -0.989581000 -0.207315036 -1.771846963  0.077145314 -1.060696087 -0.136199948
[127] -0.705120649 -0.420660299 -0.705120649  0.646066015 -0.776235737 -0.278430124 -0.562890474
[134] -0.136199948 -0.989581000 -0.776235737 -0.705120649 -0.065084861 -1.131811175 -0.562890474
[141] -0.562890474 -0.989581000 -0.918465912 -0.776235737 -0.634005562 -1.131811175 -0.776235737
[148] -1.202926262 -0.420660299 -0.562890474 -0.989581000  0.006030227  0.717181103  2.068367767
[155]  0.646066015  1.214986716  1.001641453  0.646066015  0.717181103  1.286101803  0.574950927
[162]  1.001641453  0.930526365  1.072756541  0.930526365  0.859411278  0.646066015  1.143871628
[169]  0.646066015  1.428331979  0.574950927  1.499447066  1.214986716  1.001641453  0.859411278
[176]  1.001641453  1.001641453  1.001641453  1.072756541  1.001641453  0.646066015  1.357216891
[183]  1.499447066  0.574950927  0.432720752  2.068367767  1.357216891  1.357216891  0.859411278
[190]  1.286101803  0.503835840  0.503835840  0.503835840  1.712792329  0.646066015  1.072756541
[197]  1.499447066  1.143871628  0.646066015  1.712792329  0.859411278  1.001641453  0.646066015
[204]  1.357216891  0.646066015  1.712792329  1.143871628  1.357216891  0.503835840  1.357216891
[211]  0.503835840  1.641677241  0.503835840  1.428331979  0.930526365  2.139482854  1.286101803
[218]  2.068367767  0.930526365  1.997252679  1.357216891  1.570562154  1.072756541  1.428331979
[225]  1.428331979  1.143871628  1.072756541  2.068367767  0.574950927  1.357216891  1.001641453
[232]  1.570562154  0.788296190  1.428331979  0.788296190  1.641677241  0.788296190  1.926137592
[239]  1.214986716  1.214986716  0.788296190  2.068367767  1.214986716  1.926137592  0.788296190
[246]  1.641677241  0.930526365  1.783907417  1.072756541  1.499447066  0.148260402  1.712792329
[253]  1.286101803  1.926137592  1.001641453  1.926137592  1.072756541  1.001641453  0.646066015
[260]  1.286101803  0.503835840  0.574950927  1.072756541  1.997252679  0.859411278  2.068367767
[267]  1.143871628  2.068367767  1.143871628  1.499447066  0.930526365           NA  1.001641453
[274]  1.499447066  0.788296190  0.859411278 -0.634005562 -0.349545211 -0.562890474 -0.918465912
[281] -0.278430124 -0.207315036 -1.629616788 -0.278430124 -0.420660299 -0.207315036 -0.562890474
[288] -0.491775386 -1.131811175  0.006030227 -0.776235737  0.006030227 -0.278430124 -1.416271525
[295] -0.776235737 -0.420660299 -1.416271525 -0.705120649 -0.989581000 -0.562890474 -0.420660299
[302] -0.278430124 -0.065084861 -0.065084861 -0.705120649  0.290490577 -0.989581000  0.006030227
[309] -0.989581000  0.148260402 -0.420660299 -0.136199948 -0.420660299  0.646066015 -0.634005562
[316]  0.290490577  0.646066015 -0.989581000 -0.349545211 -0.349545211 -0.349545211  0.006030227
[323] -0.776235737  0.788296190 -0.989581000 -0.207315036 -0.136199948  0.006030227 -0.562890474
[330]  0.148260402 -0.989581000 -0.278430124 -0.705120649  0.148260402  0.077145314 -0.491775386
[337]  0.361605665 -0.847350824 -0.420660299  0.432720752  0.077145314 -0.562890474  0.646066015
[344] -0.207315036
penguins %>% 
  select(contains("mm")) %>% 
  map(.x = ., .f = function(.x) { (.x - mean(.x, na.rm = T)) / sd(.x, na.rm = T) })
$bill_length_mm
  [1] -0.88320467 -0.80993901 -0.66340769          NA -1.32279862 -0.84657184 -0.91983750
  [8] -0.86488825 -1.79902541 -0.35202864 -1.12131806 -1.12131806 -0.51687637 -0.97478674
 [15] -1.70744334 -1.34111504 -0.95647033 -0.26044656 -1.74407616  0.38062795 -1.12131806
 [22] -1.13963448 -1.46932994 -1.04805240 -0.93815391 -1.57922843 -0.60845845 -0.62677486
 [29] -1.10300165 -0.62677486 -0.80993901 -1.23121655 -0.80993901 -0.55350920 -1.37774787
 [36] -0.86488825 -0.93815391 -0.31539581 -1.15795089 -0.75498976 -1.35943145 -0.57182562
 [43] -1.45101353  0.03261607 -1.26784938 -0.79162259 -0.51687637 -1.17626731 -1.45101353
 [50] -0.29707939 -0.79162259 -0.70004052 -1.63417768 -0.35202864 -1.72575975 -0.46192713
 [57] -0.90152108 -0.60845845 -1.35943145 -1.15795089 -1.50596277 -0.48024354 -1.15795089
 [64] -0.51687637 -1.37774787 -0.42529430 -1.54259560 -0.51687637 -1.46932994 -0.38866147
 [71] -1.90892390 -0.77330618 -0.79162259  0.34399512 -1.54259560 -0.20549732 -0.55350920
 [78] -1.23121655 -1.41438070 -0.33371222 -1.70744334 -0.18718091 -1.32279862 -1.61586126
 [85] -1.21290014 -0.48024354 -1.39606428 -1.28616579 -1.02973599 -0.91983750 -1.50596277
 [92] -0.51687637 -1.81734182 -0.79162259 -1.41438070 -0.57182562 -1.06636882 -0.66340769
 [99] -1.98218956 -0.13223166 -1.63417768 -0.53519279 -1.13963448 -1.12131806 -1.10300165
[106] -0.77330618 -0.97478674 -1.04805240 -1.06636882 -0.13223166 -1.06636882  0.30736229
[113] -0.77330618 -0.31539581 -0.79162259 -0.22381374 -0.97478674 -1.21290014 -1.50596277
[120] -0.51687637 -1.41438070 -1.13963448 -0.68172411 -0.46192713 -1.59754485 -0.60845845
[127] -0.93815391 -0.44361071 -0.90152108  0.03261607 -0.99310316 -0.15054808 -1.30448221
[134] -1.17626731 -1.06636882 -0.51687637 -1.52427919 -0.68172411 -1.26784938 -0.77330618
[141] -0.68172411 -0.60845845 -2.16535371 -0.59014203 -1.21290014 -0.90152108 -0.86488825
[148] -1.34111504 -1.45101353 -1.12131806 -1.45101353 -0.44361071  0.39894437  1.11328455
[155]  0.87517115  1.11328455  0.67369059  0.47221003  0.27072946  0.50884286 -0.11391525
[162]  0.52715927 -0.55350920  0.93012040  0.28904588  0.82022191  0.34399512  0.98506964
[169] -0.35202864  0.96675323  0.41726078  0.87517115  1.14991738  0.21578022  0.47221003
[176]  0.43557720 -0.18718091  0.39894437  0.10588173  0.71032342  0.78358908  1.11328455
[183]  0.61874135 -0.20549732  0.21578022  2.87166037  0.94843681  0.82022191 -0.24213015
[190]  0.08756532  0.01429966  0.87517115 -0.22381374  1.04001889  0.25241305  1.04001889
[197]  1.20486662 -0.05896600  0.28904588  1.20486662  0.17914739  0.23409663  0.49052644
[204]  0.83853832  0.21578022  1.13160096  0.47221003  0.19746381 -0.02233317  0.28904588
[211] -0.13223166  1.18655021  0.25241305  0.41726078  0.32567871  1.90089038  0.34399512
[218]  1.07665172  0.41726078  1.02170247 -0.07728242  1.24149945  0.69200701  0.45389361
[225]  0.78358908  0.47221003  0.45389361  0.85685474  0.65537418  1.31476511  0.23409663
[232]  0.23409663  0.94843681  1.57119492  0.63705776  1.11328455  0.17914739  1.25981586
[239] -0.09559883  1.35139794  0.65537418  1.49792926  0.65537418  1.51624567  0.28904588
[246]  1.02170247  0.10588173  1.25981586  1.00338606  0.54547569  0.82022191  1.31476511
[253]  0.83853832  2.19395302  0.60042493  0.94843681  0.61874135  0.52715927 -0.40697788
[260]  1.73604265 -0.11391525  0.76527266  1.20486662  1.07665172 -0.07728242  1.38803077
[267]  0.41726078  2.04742170  0.10588173  0.89348757  0.60042493          NA  0.52715927
[274]  1.18655021  0.23409663  1.09496813  0.47221003  1.11328455  1.35139794  0.27072946
[281]  1.60782775  0.23409663  0.39894437  1.35139794  0.38062795  1.35139794  0.49052644
[288]  1.42466360  0.56379210  1.47961284  0.36231154  1.20486662  1.16823379  2.57859773
[295]  0.45389361  0.96675323 -0.27876298  0.83853832 -0.13223166  1.22318303  0.50884286
[302]  1.47961284  1.20486662  1.02170247  0.45389361  1.62614416 -0.55350920  1.88257397
[309] -0.26044656  1.29644869  1.05833530  0.65537418  0.67369059  1.47961284  0.54547569
[316]  1.75435906  0.93012040  0.41726078  1.27813228  0.28904588  1.27813228  1.25981586
[323]  1.13160096  0.93012040  1.38803077  1.07665172  0.76527266  1.36971435  0.32567871
[330]  1.24149945 -0.26044656  1.51624567  0.23409663  0.98506964  1.14991738  0.30736229
[337]  1.46129643  0.52715927  0.32567871  2.17563660 -0.07728242  1.04001889  1.25981586
[344]  1.14991738

$bill_depth_mm
  [1]  0.78430007  0.12600328  0.42983257          NA  1.08812936  1.74642615  0.32855614
  [8]  1.24004400  0.48047078  1.54387329 -0.02591137  0.07536506  0.22727971  2.05025544
 [15]  1.99961722  0.32855614  0.93621471  1.79706436  0.63238542  2.20217008  0.58174721
 [22]  0.78430007  1.03749114  0.48047078  0.02472685  0.88557650  0.73366185  0.37919435
 [29]  0.73366185  0.88557650 -0.22846423  0.48047078  0.32855614  0.88557650 -0.07654958
 [36]  1.99961722  1.44259686  0.68302364  1.08812936  0.98685293  0.42983257  0.63238542
 [43]  0.68302364  1.29068222 -0.12718780  0.83493828  0.93621471  0.88557650  0.37919435
 [50]  2.05025544  0.27791792  0.88557650  0.37919435  1.18940579  0.48047078  0.73366185
 [57]  0.17664149  0.83493828 -0.27910244  0.98685293 -0.12718780  1.99961722 -0.07654958
 [64]  0.53110900 -0.02591137  0.42983257 -0.48165530  0.98685293 -0.27910244  1.13876757
 [71]  0.93621471  0.63238542  0.02472685  0.88557650  0.17664149  0.68302364 -0.17782601
 [78]  1.13876757 -0.53229351  0.98685293  0.02472685  0.22727971  0.83493828  1.13876757
 [85]  0.32855614  1.59451151  1.18940579  0.73366185  1.03749114  0.83493828  0.42983257
 [92]  0.48047078 -0.02591137  0.48047078  0.07536506  0.88557650  0.73366185  0.68302364
 [99] -0.53229351  0.68302364  0.37919435  1.44259686 -0.58293173  1.44259686  0.73366185
[106]  0.88557650  0.02472685  1.44259686 -0.07654958  0.93621471 -0.32974066  1.59451151
[113]  0.27791792  1.18940579  1.79706436  0.58174721 -0.07654958  1.69578793 -0.07654958
[120]  0.73366185  0.02472685  1.34132043 -0.07654958  0.68302364 -0.63356994  0.93621471
[127]  0.22727971  0.58174721 -0.02591137  0.42983257  0.37919435  1.03749114  0.68302364
[134]  0.68302364  0.22727971  0.17664149  0.17664149  1.49323508 -0.32974066  0.37919435
[141] -0.02591137  0.02472685 -0.83612280 -0.07654958 -0.17782601  0.78430007  0.73366185
[148]  0.63238542  0.32855614  0.48047078 -0.02591137  0.68302364 -2.00080174 -0.43101709
[155] -1.54505781 -0.98803745 -1.34250495 -1.84888710 -1.29186674 -0.93739923 -1.89952531
[162] -0.88676102 -1.74761067 -0.53229351 -1.74761067 -1.29186674 -1.29186674 -0.73484637
[169] -1.84888710 -0.98803745 -1.34250495 -1.03867566 -1.44378138 -1.34250495 -1.34250495
[176] -0.68420816 -2.05143996 -1.03867566 -1.44378138 -1.08931388 -1.44378138 -0.93739923
[183] -0.93739923 -1.49441960 -1.34250495 -0.07654958 -1.19059031 -0.43101709 -1.74761067
[190]  0.07536506 -1.79824888 -0.73484637 -1.74761067 -0.58293173 -1.74761067 -1.08931388
[197] -0.63356994 -1.64633424 -1.64633424 -0.63356994 -1.95016353 -0.68420816 -1.49441960
[204] -1.54505781 -1.39314317 -1.08931388 -1.39314317 -0.88676102 -1.64633424 -1.08931388
[211] -1.34250495 -0.93739923 -1.69697245 -1.13995209 -1.64633424 -0.73484637 -1.49441960
[218] -0.17782601 -1.39314317 -0.48165530 -1.49441960 -1.08931388 -1.08931388 -0.78548459
[225] -0.78548459 -1.19059031 -1.08931388 -0.58293173 -1.49441960 -0.43101709 -1.69697245
[232] -0.38037887 -1.34250495 -0.78548459 -1.29186674 -0.63356994 -1.69697245  0.07536506
[239] -1.39314317 -1.49441960 -1.59569603 -0.07654958 -1.08931388 -0.02591137 -1.34250495
[246] -0.53229351 -1.24122852 -0.73484637 -0.68420816 -1.29186674 -1.39314317 -0.32974066
[253] -1.08931388 -0.07654958 -0.83612280 -1.08931388 -1.69697245 -0.53229351 -1.24122852
[260] -0.68420816 -1.59569603 -1.03867566 -0.98803745 -0.63356994 -0.98803745 -0.43101709
[267] -1.54505781 -0.58293173 -0.73484637 -0.48165530 -1.74761067          NA -1.44378138
[274] -0.73484637 -1.19059031 -0.53229351  0.37919435  1.18940579  1.03749114  0.78430007
[281]  1.34132043  0.32855614  0.53110900  0.53110900  0.88557650  1.39195865  0.32855614
[288]  1.59451151  0.07536506  0.48047078 -0.02591137  1.24004400  1.44259686  0.32855614
[295]  0.73366185  0.53110900  0.07536506  0.17664149 -0.27910244  1.13876757  0.37919435
[302]  0.93621471  0.63238542  0.93621471  0.32855614  1.44259686 -0.27910244  1.84770258
[309] -0.22846423  0.83493828  0.73366185 -0.17782601  0.58174721  1.79706436 -0.27910244
[316]  1.39195865  1.18940579  0.17664149  0.98685293 -0.07654958  0.37919435  0.68302364
[323]  0.37919435  1.24004400  0.78430007  0.07536506 -0.38037887  0.93621471  0.07536506
[330]  1.29068222  0.07536506  0.83493828 -0.27910244  1.39195865  0.83493828  1.13876757
[337]  1.18940579 -0.32974066 -0.07654958  1.34132043  0.48047078  0.53110900  0.93621471
[344]  0.78430007

$flipper_length_mm
  [1] -1.416271525 -1.060696087 -0.420660299           NA -0.562890474 -0.776235737 -1.416271525
  [8] -0.420660299 -0.562890474 -0.776235737 -1.060696087 -1.487386613 -1.345156438 -0.705120649
 [15] -0.207315036 -1.131811175 -0.420660299 -0.278430124 -1.202926262 -0.491775386 -1.914077138
 [22] -1.487386613 -0.847350824 -1.131811175 -1.487386613 -0.989581000 -1.274041350 -0.989581000
 [29] -2.056307313 -1.487386613 -1.629616788 -1.629616788 -0.918465912 -1.202926262 -0.420660299
 [36] -0.349545211 -0.776235737 -1.487386613 -1.416271525 -1.202926262 -1.345156438 -0.420660299
 [43] -1.060696087 -0.349545211 -1.131811175 -0.776235737 -1.345156438 -1.558501700 -0.776235737
 [50] -0.705120649 -1.060696087 -0.918465912 -0.776235737 -0.065084861 -0.989581000 -0.705120649
 [57] -1.060696087 -0.562890474 -1.416271525 -0.491775386 -1.131811175 -0.420660299 -1.131811175
 [64] -0.634005562 -1.202926262 -0.634005562 -0.420660299 -0.918465912 -0.776235737 -0.207315036
 [71] -0.776235737 -0.776235737 -0.349545211 -0.278430124 -0.776235737 -0.420660299 -0.705120649
 [78] -1.202926262 -0.989581000 -0.420660299 -0.847350824 -0.349545211 -0.989581000 -0.562890474
 [85] -0.705120649 -0.491775386 -0.776235737 -0.847350824 -0.847350824 -0.776235737  0.077145314
 [92]  0.290490577 -1.131811175 -1.060696087 -0.989581000  0.503835840 -0.776235737 -0.349545211
 [99] -1.629616788 -0.634005562 -0.634005562  0.148260402 -1.274041350 -0.776235737 -0.562890474
[106] -1.202926262 -0.136199948 -0.776235737 -1.416271525 -0.278430124 -0.207315036 -0.705120649
[113] -0.562890474 -0.278430124 -0.705120649 -0.349545211 -0.918465912 -0.136199948 -0.847350824
[120] -0.847350824 -0.989581000 -0.207315036 -1.771846963  0.077145314 -1.060696087 -0.136199948
[127] -0.705120649 -0.420660299 -0.705120649  0.646066015 -0.776235737 -0.278430124 -0.562890474
[134] -0.136199948 -0.989581000 -0.776235737 -0.705120649 -0.065084861 -1.131811175 -0.562890474
[141] -0.562890474 -0.989581000 -0.918465912 -0.776235737 -0.634005562 -1.131811175 -0.776235737
[148] -1.202926262 -0.420660299 -0.562890474 -0.989581000  0.006030227  0.717181103  2.068367767
[155]  0.646066015  1.214986716  1.001641453  0.646066015  0.717181103  1.286101803  0.574950927
[162]  1.001641453  0.930526365  1.072756541  0.930526365  0.859411278  0.646066015  1.143871628
[169]  0.646066015  1.428331979  0.574950927  1.499447066  1.214986716  1.001641453  0.859411278
[176]  1.001641453  1.001641453  1.001641453  1.072756541  1.001641453  0.646066015  1.357216891
[183]  1.499447066  0.574950927  0.432720752  2.068367767  1.357216891  1.357216891  0.859411278
[190]  1.286101803  0.503835840  0.503835840  0.503835840  1.712792329  0.646066015  1.072756541
[197]  1.499447066  1.143871628  0.646066015  1.712792329  0.859411278  1.001641453  0.646066015
[204]  1.357216891  0.646066015  1.712792329  1.143871628  1.357216891  0.503835840  1.357216891
[211]  0.503835840  1.641677241  0.503835840  1.428331979  0.930526365  2.139482854  1.286101803
[218]  2.068367767  0.930526365  1.997252679  1.357216891  1.570562154  1.072756541  1.428331979
[225]  1.428331979  1.143871628  1.072756541  2.068367767  0.574950927  1.357216891  1.001641453
[232]  1.570562154  0.788296190  1.428331979  0.788296190  1.641677241  0.788296190  1.926137592
[239]  1.214986716  1.214986716  0.788296190  2.068367767  1.214986716  1.926137592  0.788296190
[246]  1.641677241  0.930526365  1.783907417  1.072756541  1.499447066  0.148260402  1.712792329
[253]  1.286101803  1.926137592  1.001641453  1.926137592  1.072756541  1.001641453  0.646066015
[260]  1.286101803  0.503835840  0.574950927  1.072756541  1.997252679  0.859411278  2.068367767
[267]  1.143871628  2.068367767  1.143871628  1.499447066  0.930526365           NA  1.001641453
[274]  1.499447066  0.788296190  0.859411278 -0.634005562 -0.349545211 -0.562890474 -0.918465912
[281] -0.278430124 -0.207315036 -1.629616788 -0.278430124 -0.420660299 -0.207315036 -0.562890474
[288] -0.491775386 -1.131811175  0.006030227 -0.776235737  0.006030227 -0.278430124 -1.416271525
[295] -0.776235737 -0.420660299 -1.416271525 -0.705120649 -0.989581000 -0.562890474 -0.420660299
[302] -0.278430124 -0.065084861 -0.065084861 -0.705120649  0.290490577 -0.989581000  0.006030227
[309] -0.989581000  0.148260402 -0.420660299 -0.136199948 -0.420660299  0.646066015 -0.634005562
[316]  0.290490577  0.646066015 -0.989581000 -0.349545211 -0.349545211 -0.349545211  0.006030227
[323] -0.776235737  0.788296190 -0.989581000 -0.207315036 -0.136199948  0.006030227 -0.562890474
[330]  0.148260402 -0.989581000 -0.278430124 -0.705120649  0.148260402  0.077145314 -0.491775386
[337]  0.361605665 -0.847350824 -0.420660299  0.432720752  0.077145314 -0.562890474  0.646066015
[344] -0.207315036
penguins %>% 
  select(contains("mm")) %>% 
  map(.x = ., .f = ~(.x - mean(.x, na.rm = T)) / sd(.x, na.rm = T))
$bill_length_mm
  [1] -0.88320467 -0.80993901 -0.66340769          NA -1.32279862 -0.84657184 -0.91983750
  [8] -0.86488825 -1.79902541 -0.35202864 -1.12131806 -1.12131806 -0.51687637 -0.97478674
 [15] -1.70744334 -1.34111504 -0.95647033 -0.26044656 -1.74407616  0.38062795 -1.12131806
 [22] -1.13963448 -1.46932994 -1.04805240 -0.93815391 -1.57922843 -0.60845845 -0.62677486
 [29] -1.10300165 -0.62677486 -0.80993901 -1.23121655 -0.80993901 -0.55350920 -1.37774787
 [36] -0.86488825 -0.93815391 -0.31539581 -1.15795089 -0.75498976 -1.35943145 -0.57182562
 [43] -1.45101353  0.03261607 -1.26784938 -0.79162259 -0.51687637 -1.17626731 -1.45101353
 [50] -0.29707939 -0.79162259 -0.70004052 -1.63417768 -0.35202864 -1.72575975 -0.46192713
 [57] -0.90152108 -0.60845845 -1.35943145 -1.15795089 -1.50596277 -0.48024354 -1.15795089
 [64] -0.51687637 -1.37774787 -0.42529430 -1.54259560 -0.51687637 -1.46932994 -0.38866147
 [71] -1.90892390 -0.77330618 -0.79162259  0.34399512 -1.54259560 -0.20549732 -0.55350920
 [78] -1.23121655 -1.41438070 -0.33371222 -1.70744334 -0.18718091 -1.32279862 -1.61586126
 [85] -1.21290014 -0.48024354 -1.39606428 -1.28616579 -1.02973599 -0.91983750 -1.50596277
 [92] -0.51687637 -1.81734182 -0.79162259 -1.41438070 -0.57182562 -1.06636882 -0.66340769
 [99] -1.98218956 -0.13223166 -1.63417768 -0.53519279 -1.13963448 -1.12131806 -1.10300165
[106] -0.77330618 -0.97478674 -1.04805240 -1.06636882 -0.13223166 -1.06636882  0.30736229
[113] -0.77330618 -0.31539581 -0.79162259 -0.22381374 -0.97478674 -1.21290014 -1.50596277
[120] -0.51687637 -1.41438070 -1.13963448 -0.68172411 -0.46192713 -1.59754485 -0.60845845
[127] -0.93815391 -0.44361071 -0.90152108  0.03261607 -0.99310316 -0.15054808 -1.30448221
[134] -1.17626731 -1.06636882 -0.51687637 -1.52427919 -0.68172411 -1.26784938 -0.77330618
[141] -0.68172411 -0.60845845 -2.16535371 -0.59014203 -1.21290014 -0.90152108 -0.86488825
[148] -1.34111504 -1.45101353 -1.12131806 -1.45101353 -0.44361071  0.39894437  1.11328455
[155]  0.87517115  1.11328455  0.67369059  0.47221003  0.27072946  0.50884286 -0.11391525
[162]  0.52715927 -0.55350920  0.93012040  0.28904588  0.82022191  0.34399512  0.98506964
[169] -0.35202864  0.96675323  0.41726078  0.87517115  1.14991738  0.21578022  0.47221003
[176]  0.43557720 -0.18718091  0.39894437  0.10588173  0.71032342  0.78358908  1.11328455
[183]  0.61874135 -0.20549732  0.21578022  2.87166037  0.94843681  0.82022191 -0.24213015
[190]  0.08756532  0.01429966  0.87517115 -0.22381374  1.04001889  0.25241305  1.04001889
[197]  1.20486662 -0.05896600  0.28904588  1.20486662  0.17914739  0.23409663  0.49052644
[204]  0.83853832  0.21578022  1.13160096  0.47221003  0.19746381 -0.02233317  0.28904588
[211] -0.13223166  1.18655021  0.25241305  0.41726078  0.32567871  1.90089038  0.34399512
[218]  1.07665172  0.41726078  1.02170247 -0.07728242  1.24149945  0.69200701  0.45389361
[225]  0.78358908  0.47221003  0.45389361  0.85685474  0.65537418  1.31476511  0.23409663
[232]  0.23409663  0.94843681  1.57119492  0.63705776  1.11328455  0.17914739  1.25981586
[239] -0.09559883  1.35139794  0.65537418  1.49792926  0.65537418  1.51624567  0.28904588
[246]  1.02170247  0.10588173  1.25981586  1.00338606  0.54547569  0.82022191  1.31476511
[253]  0.83853832  2.19395302  0.60042493  0.94843681  0.61874135  0.52715927 -0.40697788
[260]  1.73604265 -0.11391525  0.76527266  1.20486662  1.07665172 -0.07728242  1.38803077
[267]  0.41726078  2.04742170  0.10588173  0.89348757  0.60042493          NA  0.52715927
[274]  1.18655021  0.23409663  1.09496813  0.47221003  1.11328455  1.35139794  0.27072946
[281]  1.60782775  0.23409663  0.39894437  1.35139794  0.38062795  1.35139794  0.49052644
[288]  1.42466360  0.56379210  1.47961284  0.36231154  1.20486662  1.16823379  2.57859773
[295]  0.45389361  0.96675323 -0.27876298  0.83853832 -0.13223166  1.22318303  0.50884286
[302]  1.47961284  1.20486662  1.02170247  0.45389361  1.62614416 -0.55350920  1.88257397
[309] -0.26044656  1.29644869  1.05833530  0.65537418  0.67369059  1.47961284  0.54547569
[316]  1.75435906  0.93012040  0.41726078  1.27813228  0.28904588  1.27813228  1.25981586
[323]  1.13160096  0.93012040  1.38803077  1.07665172  0.76527266  1.36971435  0.32567871
[330]  1.24149945 -0.26044656  1.51624567  0.23409663  0.98506964  1.14991738  0.30736229
[337]  1.46129643  0.52715927  0.32567871  2.17563660 -0.07728242  1.04001889  1.25981586
[344]  1.14991738

$bill_depth_mm
  [1]  0.78430007  0.12600328  0.42983257          NA  1.08812936  1.74642615  0.32855614
  [8]  1.24004400  0.48047078  1.54387329 -0.02591137  0.07536506  0.22727971  2.05025544
 [15]  1.99961722  0.32855614  0.93621471  1.79706436  0.63238542  2.20217008  0.58174721
 [22]  0.78430007  1.03749114  0.48047078  0.02472685  0.88557650  0.73366185  0.37919435
 [29]  0.73366185  0.88557650 -0.22846423  0.48047078  0.32855614  0.88557650 -0.07654958
 [36]  1.99961722  1.44259686  0.68302364  1.08812936  0.98685293  0.42983257  0.63238542
 [43]  0.68302364  1.29068222 -0.12718780  0.83493828  0.93621471  0.88557650  0.37919435
 [50]  2.05025544  0.27791792  0.88557650  0.37919435  1.18940579  0.48047078  0.73366185
 [57]  0.17664149  0.83493828 -0.27910244  0.98685293 -0.12718780  1.99961722 -0.07654958
 [64]  0.53110900 -0.02591137  0.42983257 -0.48165530  0.98685293 -0.27910244  1.13876757
 [71]  0.93621471  0.63238542  0.02472685  0.88557650  0.17664149  0.68302364 -0.17782601
 [78]  1.13876757 -0.53229351  0.98685293  0.02472685  0.22727971  0.83493828  1.13876757
 [85]  0.32855614  1.59451151  1.18940579  0.73366185  1.03749114  0.83493828  0.42983257
 [92]  0.48047078 -0.02591137  0.48047078  0.07536506  0.88557650  0.73366185  0.68302364
 [99] -0.53229351  0.68302364  0.37919435  1.44259686 -0.58293173  1.44259686  0.73366185
[106]  0.88557650  0.02472685  1.44259686 -0.07654958  0.93621471 -0.32974066  1.59451151
[113]  0.27791792  1.18940579  1.79706436  0.58174721 -0.07654958  1.69578793 -0.07654958
[120]  0.73366185  0.02472685  1.34132043 -0.07654958  0.68302364 -0.63356994  0.93621471
[127]  0.22727971  0.58174721 -0.02591137  0.42983257  0.37919435  1.03749114  0.68302364
[134]  0.68302364  0.22727971  0.17664149  0.17664149  1.49323508 -0.32974066  0.37919435
[141] -0.02591137  0.02472685 -0.83612280 -0.07654958 -0.17782601  0.78430007  0.73366185
[148]  0.63238542  0.32855614  0.48047078 -0.02591137  0.68302364 -2.00080174 -0.43101709
[155] -1.54505781 -0.98803745 -1.34250495 -1.84888710 -1.29186674 -0.93739923 -1.89952531
[162] -0.88676102 -1.74761067 -0.53229351 -1.74761067 -1.29186674 -1.29186674 -0.73484637
[169] -1.84888710 -0.98803745 -1.34250495 -1.03867566 -1.44378138 -1.34250495 -1.34250495
[176] -0.68420816 -2.05143996 -1.03867566 -1.44378138 -1.08931388 -1.44378138 -0.93739923
[183] -0.93739923 -1.49441960 -1.34250495 -0.07654958 -1.19059031 -0.43101709 -1.74761067
[190]  0.07536506 -1.79824888 -0.73484637 -1.74761067 -0.58293173 -1.74761067 -1.08931388
[197] -0.63356994 -1.64633424 -1.64633424 -0.63356994 -1.95016353 -0.68420816 -1.49441960
[204] -1.54505781 -1.39314317 -1.08931388 -1.39314317 -0.88676102 -1.64633424 -1.08931388
[211] -1.34250495 -0.93739923 -1.69697245 -1.13995209 -1.64633424 -0.73484637 -1.49441960
[218] -0.17782601 -1.39314317 -0.48165530 -1.49441960 -1.08931388 -1.08931388 -0.78548459
[225] -0.78548459 -1.19059031 -1.08931388 -0.58293173 -1.49441960 -0.43101709 -1.69697245
[232] -0.38037887 -1.34250495 -0.78548459 -1.29186674 -0.63356994 -1.69697245  0.07536506
[239] -1.39314317 -1.49441960 -1.59569603 -0.07654958 -1.08931388 -0.02591137 -1.34250495
[246] -0.53229351 -1.24122852 -0.73484637 -0.68420816 -1.29186674 -1.39314317 -0.32974066
[253] -1.08931388 -0.07654958 -0.83612280 -1.08931388 -1.69697245 -0.53229351 -1.24122852
[260] -0.68420816 -1.59569603 -1.03867566 -0.98803745 -0.63356994 -0.98803745 -0.43101709
[267] -1.54505781 -0.58293173 -0.73484637 -0.48165530 -1.74761067          NA -1.44378138
[274] -0.73484637 -1.19059031 -0.53229351  0.37919435  1.18940579  1.03749114  0.78430007
[281]  1.34132043  0.32855614  0.53110900  0.53110900  0.88557650  1.39195865  0.32855614
[288]  1.59451151  0.07536506  0.48047078 -0.02591137  1.24004400  1.44259686  0.32855614
[295]  0.73366185  0.53110900  0.07536506  0.17664149 -0.27910244  1.13876757  0.37919435
[302]  0.93621471  0.63238542  0.93621471  0.32855614  1.44259686 -0.27910244  1.84770258
[309] -0.22846423  0.83493828  0.73366185 -0.17782601  0.58174721  1.79706436 -0.27910244
[316]  1.39195865  1.18940579  0.17664149  0.98685293 -0.07654958  0.37919435  0.68302364
[323]  0.37919435  1.24004400  0.78430007  0.07536506 -0.38037887  0.93621471  0.07536506
[330]  1.29068222  0.07536506  0.83493828 -0.27910244  1.39195865  0.83493828  1.13876757
[337]  1.18940579 -0.32974066 -0.07654958  1.34132043  0.48047078  0.53110900  0.93621471
[344]  0.78430007

$flipper_length_mm
  [1] -1.416271525 -1.060696087 -0.420660299           NA -0.562890474 -0.776235737 -1.416271525
  [8] -0.420660299 -0.562890474 -0.776235737 -1.060696087 -1.487386613 -1.345156438 -0.705120649
 [15] -0.207315036 -1.131811175 -0.420660299 -0.278430124 -1.202926262 -0.491775386 -1.914077138
 [22] -1.487386613 -0.847350824 -1.131811175 -1.487386613 -0.989581000 -1.274041350 -0.989581000
 [29] -2.056307313 -1.487386613 -1.629616788 -1.629616788 -0.918465912 -1.202926262 -0.420660299
 [36] -0.349545211 -0.776235737 -1.487386613 -1.416271525 -1.202926262 -1.345156438 -0.420660299
 [43] -1.060696087 -0.349545211 -1.131811175 -0.776235737 -1.345156438 -1.558501700 -0.776235737
 [50] -0.705120649 -1.060696087 -0.918465912 -0.776235737 -0.065084861 -0.989581000 -0.705120649
 [57] -1.060696087 -0.562890474 -1.416271525 -0.491775386 -1.131811175 -0.420660299 -1.131811175
 [64] -0.634005562 -1.202926262 -0.634005562 -0.420660299 -0.918465912 -0.776235737 -0.207315036
 [71] -0.776235737 -0.776235737 -0.349545211 -0.278430124 -0.776235737 -0.420660299 -0.705120649
 [78] -1.202926262 -0.989581000 -0.420660299 -0.847350824 -0.349545211 -0.989581000 -0.562890474
 [85] -0.705120649 -0.491775386 -0.776235737 -0.847350824 -0.847350824 -0.776235737  0.077145314
 [92]  0.290490577 -1.131811175 -1.060696087 -0.989581000  0.503835840 -0.776235737 -0.349545211
 [99] -1.629616788 -0.634005562 -0.634005562  0.148260402 -1.274041350 -0.776235737 -0.562890474
[106] -1.202926262 -0.136199948 -0.776235737 -1.416271525 -0.278430124 -0.207315036 -0.705120649
[113] -0.562890474 -0.278430124 -0.705120649 -0.349545211 -0.918465912 -0.136199948 -0.847350824
[120] -0.847350824 -0.989581000 -0.207315036 -1.771846963  0.077145314 -1.060696087 -0.136199948
[127] -0.705120649 -0.420660299 -0.705120649  0.646066015 -0.776235737 -0.278430124 -0.562890474
[134] -0.136199948 -0.989581000 -0.776235737 -0.705120649 -0.065084861 -1.131811175 -0.562890474
[141] -0.562890474 -0.989581000 -0.918465912 -0.776235737 -0.634005562 -1.131811175 -0.776235737
[148] -1.202926262 -0.420660299 -0.562890474 -0.989581000  0.006030227  0.717181103  2.068367767
[155]  0.646066015  1.214986716  1.001641453  0.646066015  0.717181103  1.286101803  0.574950927
[162]  1.001641453  0.930526365  1.072756541  0.930526365  0.859411278  0.646066015  1.143871628
[169]  0.646066015  1.428331979  0.574950927  1.499447066  1.214986716  1.001641453  0.859411278
[176]  1.001641453  1.001641453  1.001641453  1.072756541  1.001641453  0.646066015  1.357216891
[183]  1.499447066  0.574950927  0.432720752  2.068367767  1.357216891  1.357216891  0.859411278
[190]  1.286101803  0.503835840  0.503835840  0.503835840  1.712792329  0.646066015  1.072756541
[197]  1.499447066  1.143871628  0.646066015  1.712792329  0.859411278  1.001641453  0.646066015
[204]  1.357216891  0.646066015  1.712792329  1.143871628  1.357216891  0.503835840  1.357216891
[211]  0.503835840  1.641677241  0.503835840  1.428331979  0.930526365  2.139482854  1.286101803
[218]  2.068367767  0.930526365  1.997252679  1.357216891  1.570562154  1.072756541  1.428331979
[225]  1.428331979  1.143871628  1.072756541  2.068367767  0.574950927  1.357216891  1.001641453
[232]  1.570562154  0.788296190  1.428331979  0.788296190  1.641677241  0.788296190  1.926137592
[239]  1.214986716  1.214986716  0.788296190  2.068367767  1.214986716  1.926137592  0.788296190
[246]  1.641677241  0.930526365  1.783907417  1.072756541  1.499447066  0.148260402  1.712792329
[253]  1.286101803  1.926137592  1.001641453  1.926137592  1.072756541  1.001641453  0.646066015
[260]  1.286101803  0.503835840  0.574950927  1.072756541  1.997252679  0.859411278  2.068367767
[267]  1.143871628  2.068367767  1.143871628  1.499447066  0.930526365           NA  1.001641453
[274]  1.499447066  0.788296190  0.859411278 -0.634005562 -0.349545211 -0.562890474 -0.918465912
[281] -0.278430124 -0.207315036 -1.629616788 -0.278430124 -0.420660299 -0.207315036 -0.562890474
[288] -0.491775386 -1.131811175  0.006030227 -0.776235737  0.006030227 -0.278430124 -1.416271525
[295] -0.776235737 -0.420660299 -1.416271525 -0.705120649 -0.989581000 -0.562890474 -0.420660299
[302] -0.278430124 -0.065084861 -0.065084861 -0.705120649  0.290490577 -0.989581000  0.006030227
[309] -0.989581000  0.148260402 -0.420660299 -0.136199948 -0.420660299  0.646066015 -0.634005562
[316]  0.290490577  0.646066015 -0.989581000 -0.349545211 -0.349545211 -0.349545211  0.006030227
[323] -0.776235737  0.788296190 -0.989581000 -0.207315036 -0.136199948  0.006030227 -0.562890474
[330]  0.148260402 -0.989581000 -0.278430124 -0.705120649  0.148260402  0.077145314 -0.491775386
[337]  0.361605665 -0.847350824 -0.420660299  0.432720752  0.077145314 -0.562890474  0.646066015
[344] -0.207315036
penguins %>%
  map_df(class)
penguins %>%
  map_df(~sum(is.na(.)))
penguins %>%
  map_df(n_distinct)
penguins %>%
  drop_na %>% 
  group_by(sex) %>%
  group_map(~slice_max(., flipper_length_mm, n = 1), .keep = T)
[[1]]

[[2]]
NA
species <- penguins %>% distinct(species, year) %>% pull(species) #.x argument for map()
years <- penguins %>% distinct(species, year) %>% pull(year)      #.y argument for map()

map2(
  .x = species,
  .y = years,
  .f = ~{
    penguins %>%
      drop_na %>% 
      filter(species == .x, year == .y) %>% 
      ggplot() +
        geom_point(aes(x = bill_length_mm, y = body_mass_g)) +
        labs(title = glue::glue("Scatter Plot Bill Length vs. BMI ({.x}, {.y})"))
    })
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

[[8]]

[[9]]

penguins %>% 
  drop_na %>% 
  group_by(species, island) %>% 
  nest %>% 
  mutate(lin_reg = map(.x = data, .f = ~lm(body_mass_g ~ ., data = .x)))  %>% 
  mutate(coefs = map(lin_reg, ~summary(.x) %>% .$coefficients %>% as_tibble)) %>%
  select(-data, -lin_reg) %>% 
  unnest(coefs)

ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics

Univariate example: 1) Add data:

penguins %>% 
  ggplot(data = .) #equivalent to ggplot()

  1. Add aesthetics mapping:
penguins %>% 
  ggplot(
    aes(x = flipper_length_mm))

  1. Add geom:
penguins %>% 
  ggplot(aes(x = flipper_length_mm)) +
    geom_histogram(na.rm = TRUE)

penguins %>% 
  ggplot(aes(x = flipper_length_mm)) +
    geom_bar(na.rm = TRUE) 

  1. Add stat:
penguins %>% 
  ggplot(aes(x = flipper_length_mm)) +
    geom_bar(stat = "density", na.rm = TRUE) 

Use geom_density() instead of geom_bar(stat = "density"):

penguins %>% 
  ggplot(aes(x = flipper_length_mm)) +
    geom_density(na.rm = TRUE)

Bivariate example: 1) Add data:

penguins %>% 
  ggplot()

  1. Add aesthetics mapping:
penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) 
  1. Add geom:
penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(na.rm = TRUE)

penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(color = species), na.rm = TRUE) 

penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(color = bill_depth_mm), na.rm = TRUE) 

penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(color = "red", na.rm = TRUE) 

penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(shape = species), size = 4, na.rm = TRUE) 

  1. Add facets:
penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(shape = species), na.rm = TRUE) +
    facet_wrap(~year)

penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(shape = species), na.rm = TRUE) +
    facet_wrap(~year + island)

  1. scale aesthetics mapping:
penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(color = species), size = 3, na.rm = TRUE) +
    scale_colour_brewer(palette = "Set3") 

penguins %>% 
  ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
    geom_point(aes(color = species), na.rm = TRUE) +
    scale_y_log10()  

Other examples: Boxplots for numeric variables

penguins %>% 
  pivot_longer(cols = contains("mm"), names_to = "var", values_to = "val") %>% 
  drop_na  %>% 
  ggplot(aes(x = var, y = val)) +
    geom_boxplot(na.rm = TRUE) +
    geom_jitter(alpha = 0.22, width = 0.3) 

Ordered bar chart

penguins %>%
  dplyr::count(species) %>%
  dplyr::mutate(prop = n / sum(n)) %>%
  ggplot() +
    geom_col(aes(x = prop, y = forcats::fct_reorder(species, prop))) +
    scale_x_continuous(labels = scales::label_percent(1.))

Adjacent bar chart

penguins %>% 
  ggplot(aes(x = species)) +
    geom_bar(aes(fill = island), position = "dodge")

Stacked bar chart

penguins %>% 
  ggplot(aes(x = species)) +
    geom_bar(aes(fill = island), position = "stack")

penguins %>% 
  ggplot(aes(x = forcats::fct_lump(species, n = 1))) +
    geom_bar(aes(fill = island), position = "stack")

High-quality density plot

p <- penguins %>% 
  ggplot(aes(x = body_mass_g)) +
    geom_density(aes(fill = species), na.rm = T, alpha = 0.4) +
    scale_x_continuous(breaks = seq(from = 3000, to = 6000, by = 500), limits = c(2000, 7000)) +
    scale_y_continuous(labels = scales::label_comma(accuracy = 0.0001)) +
    labs(
      title = "Density Function for Three Penguin Species of Palmer Penguins",
      subtitle = "Palmer Archipelago (2007-2009)",
      caption = "Data: https://github.com/allisonhorst/palmerpenguins",
      x = "Body mass [grams]",
      y = "Statistical density"
    ) +
    theme_classic() + #also: theme_minimal()
    theme(
      legend.position = "top",
      plot.title = element_text(size = 14, face = "bold"),
      plot.subtitle = element_text(size = 12),
      plot.caption = element_text(size = 10, face = "italic"),
      axis.text.x = element_text(size = 10),
      axis.text.y = element_blank(),
      axis.title = element_text(size = 10),
    )

p

Violin Plot

penguins %>% 
  ggplot(aes(x = species, y = body_mass_g)) +
    geom_violin(aes(fill = species), na.rm = T) +
    theme_classic()

Lines of Best Fit

penguins %>% 
  drop_na %>% 
  ggplot(aes(x = flipper_length_mm,
             y = body_mass_g)) +
    geom_point(aes(color = species)) +
    geom_smooth(method = "lm", se = T)

##plotly: Interactive Web Graphics

plotly::ggplotly(p)

##patchwork: The Composer of Plots

library(patchwork)
p + p + p

library(patchwork)
p + (p / p)

LS0tDQp0aXRsZTogIk1hY2hpbmUgTGVhcm5pbmcgaW4gUjogV29ya3Nob3AgU2VyaWVzIg0Kc3VidGl0bGU6ICJJbnRyb2R1Y3Rpb24gdG8gdGhlIFRpZHl2ZXJzZSINCmF1dGhvcjogIlNpbW9uIFNjaMO2bHplbCINCmluc3RpdHV0ZTogIipSZXNlYXJjaCBUZWFtIEJlcmVucyoiDQpkYXRlOiAiMjAyMC0wOC0yMCAodXBkYXRlZDogYHIgU3lzLkRhdGUoKWApIg0KDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIG5vdGVib29rIGNvbXBsZW1lbnRzIHRoZSAiKipJbnRyb2R1Y3Rpb24gdG8gdGhlIFRpZHl2ZXJzZSoqIiB3b3Jrc2hvcCB3aGljaCBpcyBwYXJ0IG9mIHRoZSBNYWNoaW5lIExlYXJuaW5nIGluIGBSYCAod2ludGVyIHRlcm0gMjAyMC8yMSkuIEZvciB0aGUgcHVycG9zZSBvZiByZXByb2R1Y2liaWxpdHksIGl0IGNvbnRhaW5zIGFsbCBleGFtcGxlcyBhbmQgdXNlIGNhc2VzIGRpc2N1c3NlZCBpbiB0aGUgd29ya3Nob3AuDQoNCiMjIFBhY2thZ2UgTWFuYWdlbWVudA0KDQpgYGB7cn0NCiNjaGVjayBpZiBwYWNtYW4gaXMgaW5zdGFsbGVkIChpbnN0YWxsIGlmIGV2YWx1YXRlcyB0byBGQUxTRSkNCmlmICghcmVxdWlyZShwYWNtYW4pID09IFQpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQojbG9hZCAob3IgaW5zdGFsbCBpZiBwYWNtYW4gY2Fubm90IGZpbmQgYW4gZXhpc3RpbmcgaW5zdGFsbGF0aW9uKSB0aGUgcmVsZXZhbnQgcGFja2FnZXMNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgcGxvdGx5LCBwYXRjaHdvcmspDQpwYWNtYW46OnBfbG9hZF9naCgiYWxsaXNvbmhvcnN0L3BhbG1lcnBlbmd1aW5zIikNCmBgYA0KDQoNCiMjIGBwYWxtZXJwZW5ndWluc2AgRGF0YSBTZXQNCg0KYGBge3J9DQpwZW5ndWlucw0KYGBgDQoNCiMjIGBtYWdyaXR0cmA6IEEgRm9yd2FyZC1QaXBlIE9wZXJhdG9yIGZvciBSDQoNCmBgYHtyfQ0KbWVhbihzdWJzZXQocGVuZ3VpbnMsIHllYXIgPT0gMjAwNykkYm9keV9tYXNzX2csIG5hLnJtID0gVCkNCg0KI2FsdGVybmF0aXZlbHk6DQpwZW5nX2JtaV8yMDA3IDwtIHN1YnNldChwZW5ndWlucywgeWVhciA9PSAyMDA3KSRib2R5X21hc3NfZw0KbWVhbihwZW5nX2JtaV8yMDA3LCBuYS5ybSA9IFQpDQpgYGANCg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHN1YnNldCh5ZWFyID09IDIwMDcpICU+JSANCiAgLiRib2R5X21hc3NfZyAlPiUgDQogIG1lYW4obmEucm0gPSBUKQ0KYGBgDQoNCg0KIyMgYHRpYmJsZWA6IFNpbXBsZSBEYXRhIEZyYW1lcw0KDQpgdGliYmxlKClgOg0KYGBge3IsIHJlc3VsdHM9Rn0NCnRpYmJsZTo6dGliYmxlKA0KICB4ID0gYygiYSIsICJiIiksDQogIHkgPSBjKDEsIDIpLA0KICB6ID0gYyhULCBGKQ0KKQ0KYGBgDQpgdHJpYmJsZSgpYDoNCmBgYHtyLCByZXN1bHRzPUZ9DQp0aWJibGU6OnRyaWJibGUoDQogIH54LCB+eSwgIH56LA0KICAiYSIsIDEsICBULA0KICAiYiIsIDIsICBGDQopDQpgYGANCmBhc190aWJibGUoKWA6DQpgYGB7cn0NCmRmIDwtIGRhdGEuZnJhbWUoDQogIHggPSBjKCJhIiwgImIiKSwgeSA9IGMoMSwgMiksIHogPSBjKFQsIEYpDQopDQoNCnRpYmJsZTo6YXNfdGliYmxlKGRmKQ0KYGBgDQpgZW5mcmFtZSgpYDoNCmBgYHtyfQ0KYyh4ID0gImEiLCB5ID0gImIiKSAlPiUNCiAgdGliYmxlOjplbmZyYW1lKG5hbWUgPSAieCIsIHZhbHVlID0gInkiKQ0KYGBgDQoNCg0KIyMgYHJlYWRyYDogUmVhZCBSZWN0YW5ndWxhciBUZXh0IERhdGENCg0KYHdyaXRlX2NzdigpYDoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICB3cml0ZV9jc3YocGF0aCA9ICIuL3Blbmd1aW5zLmNzdiIpDQpgYGANCmByZWFkX2NzdigpYDoNCmBgYHtyfQ0KcGVuZ3VpbnMgPC0gcmVhZHI6OnJlYWRfY3N2KCIuL3Blbmd1aW5zLmNzdiIpDQpgYGANCmByZWFkX2NzdigpYCB3aXRoIGV4cGxpY2l0IGNvbHVtbiBzcGVjaWZpY2F0aW9uczoNCmBgYHtyfQ0KcmVhZHI6OnJlYWRfY3N2KA0KICAiLi9wZW5ndWlucy5jc3YiLA0KICAgIGNvbF90eXBlcyA9IGNvbHMoDQogICAgICBzcGVjaWVzID0gY29sX2NoYXJhY3RlcigpLA0KICAgICAgeWVhciA9IGNvbF9kYXRldGltZShmb3JtYXQgPSAiJVkiKSwNCiAgICAgIGlzbGFuZCA9IGNvbF9za2lwKCkNCiAgICApDQogICkNCmBgYA0KYHJlYWRfY3N2KClgIHdpdGggY2hhbmdpbmcgdGhlIGRlZmF1bHQgZm9yIGBndWVzc19tYXhgOg0KYGBge3J9DQpyZWFkcjo6cmVhZF9jc3YoZmlsZSA9ICIuL3Blbmd1aW5zLmNzdiIsIGd1ZXNzX21heCA9IDEwMDEpDQpgYGANCg0KDQojI2B0aWR5cmA6IFRpZHkgTWVzc3kgRGF0YQ0KDQpgcGl2b3RfbG9uZ2VyKClgOg0KYGBge3J9DQpwZW5ndWluc19sb25nIDwtIHBlbmd1aW5zICU+JSANCiAgI2NyZWF0ZSBpZCBjb2x1bW4gaGVyZSB0byBhc3NpZ24gZWFjaCBvYnNlcnZhdGlvbiBhIHVuaXF1ZSBrZXkNCiAgbXV0YXRlKGlkID0gZHBseXI6OnJvd19udW1iZXIoKSwgLmJlZm9yZSA9IHNwZWNpZXMpICU+JSANCiAgdGlkeXI6OnBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gY29udGFpbnMoIl9tbSIpLA0KICAgIG5hbWVzX3RvID0gIm1lYXNfdHlwZSIsIHZhbHVlc190byA9ICJtZWFzdXJlbWVudCINCiAgKQ0KDQpwZW5ndWluc19sb25nDQpgYGANCmBwaXZvdF93aWRlcigpYDoNCmBgYHtyfQ0KcGVuZ3VpbnNfbG9uZyAlPiUgDQogIHRpZHlyOjpwaXZvdF93aWRlcigNCiAgICBuYW1lc19mcm9tID0gIm1lYXNfdHlwZSIsIHZhbHVlc19mcm9tID0gIm1lYXN1cmVtZW50Ig0KICApDQpgYGANCmBuZXN0KClgOg0KYGBge3J9DQpuZXN0ZWRfcGVuZ3VpbnMgPC0gcGVuZ3VpbnMgJT4lIA0KICB0aWR5cjo6bmVzdCgNCiAgICBuZXN0ZWRfZGF0YSA9IGMoaXNsYW5kLCBiaWxsX2xlbmd0aF9tbSwgYmlsbF9kZXB0aF9tbSwgZmxpcHBlcl9sZW5ndGhfbW0sIGJvZHlfbWFzc19nLCBzZXgpDQogICkNCg0KbmVzdGVkX3Blbmd1aW5zDQpgYGANCmB1bm5lc3QoKWA6DQpgYGB7cn0NCm5lc3RlZF9wZW5ndWlucyAlPiUgDQogIHVubmVzdChjb2wgPSBuZXN0ZWRfZGF0YSkNCmBgYA0KYHVubmVzdF93aWRlcigpYCB0byB1bnBhY2sgY29sdW1uczogDQpgYGB7cn0NCm5lc3RlZF9wZW5ndWlucyAlPiUgDQogIHVubmVzdF93aWRlcihjb2wgPSBuZXN0ZWRfZGF0YSkNCmBgYA0KYHVubmVzdF9sb25nZXIoKWAgdG8gdW5wYWNrIHJvd3MgKGhlcmUgYGlzbGFuZGApOiANCmBgYHtyfQ0KbmVzdGVkX3Blbmd1aW5zICU+JSANCiAgdW5uZXN0X3dpZGVyKGNvbCA9IG5lc3RlZF9kYXRhKSAlPiUgDQogIHVubmVzdF9sb25nZXIoY29sID0gYyhpc2xhbmQpKQ0KYGBgDQpgdW5pdGUoKWA6DQpgYGB7cn0NCnVuaXRlZF9wZW5ndWlucyA8LSBwZW5ndWlucyAlPiUgDQogIHRpZHlyOjp1bml0ZShjb2wgPSAic3BlY19nZW5kZXIiLCBjKHNwZWNpZXMsIHNleCksIHNlcCA9ICJfIiwgcmVtb3ZlID0gVCkNCg0KdW5pdGVkX3Blbmd1aW5zDQpgYGANCmBzZXBhcmF0ZSgpYDoNCmBgYHtyfQ0KdW5pdGVkX3Blbmd1aW5zICU+JSANCiAgdGlkeXI6OnNlcGFyYXRlKGNvbCA9IHNwZWNfZ2VuZGVyLCBpbnRvID0gYygic3BlY2llcyIsICJzZXgiKSwgc2VwID0gIl8iLCByZW1vdmUgPSBUKQ0KYGBgDQpgY29tcGxldGUoKWAgdG8gbWFrZSBpbXBsaWNpdCBgTkFgIGV4cGxpY2l0Og0KYGBge3J9DQppbmNvbXBsX3Blbmd1aW5zIDwtIHRpYmJsZSgNCiAgc3BlY2llcyA9IGMocmVwKCJBZGVsaWUiLCAyKSwgcmVwKCJHZW50b28iLCAxKSwgcmVwKCJDaGluc3RyYXAiLCAxKSksDQogIHllYXIgPSBjKDIwMDcsIDIwMDgsIDIwMDgsIDIwMDcpLA0KICB2YWx1ZSA9IGMocm5vcm0oMywgbWVhbiA9IDUwLCBzZCA9IDE1KSwgTkEpDQopDQoNCmluY29tcGxfcGVuZ3VpbnMNCmBgYA0KYGBge3J9DQppbmNvbXBsX3Blbmd1aW5zICU+JSANCiAgdGlkeXI6OmNvbXBsZXRlKA0KICAgIHNwZWNpZXMsIHllYXIsIGZpbGwgPSBsaXN0KHZhbHVlID0gTkEpDQopDQpgYGANCmBkcm9wX25hKClgIHRvIG1ha2UgZXhwbGljaXQgYE5BYCBpbXBsaWNpdDoNCmBgYHtyfQ0KaW5jb21wbF9wZW5ndWlucyAlPiUgDQogIGRyb3BfbmEodmFsdWUpDQpgYGANCmBmaWxsKClgIHRvIHJlcGxhY2UgZXhwbGljaXQgYE5BYCB3aXRoIHByZXZpb3VzIHZhbHVlOg0KYGBge3J9DQppbmNvbXBsX3Blbmd1aW5zICU+JSANCiAgdGlkeXI6OmZpbGwodmFsdWUsIC5kaXJlY3Rpb24gPSAiZG93biIpDQpgYGANCmByZXBsYWNlX25hKClgIHRvIHJlcGxhY2UgZXhwbGljaXQgYE5BYCB3aXRoIGNvbHVtbiBtZWFuOg0KYGBge3J9DQppbmNvbXBsX3Blbmd1aW5zICU+JQ0KICB0aWR5cjo6cmVwbGFjZV9uYShyZXBsYWNlID0gbGlzdCh2YWx1ZSA9IG1lYW4oLiR2YWx1ZSwgbmEucm0gPSBUKSkpDQpgYGANCg0KDQojIyBgZHBseXJgOiBBIEdyYW1tYXIgb2YgRGF0YSBNYW5pcHVsYXRpb24NCg0KYGZpbHRlcigpYCB0byBmaWx0ZXIgZm9yIHJvd3MgdGhhdCBmdWxmaWxsIGNvbmRpdGlvbjoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBmaWx0ZXIoc3BlY2llcyA9PSAiQWRlbGllIikNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGZpbHRlcihpcy5uYShiaWxsX2xlbmd0aF9tbSkgPT0gVCkNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGZpbHRlcihiZXR3ZWVuKGJvZHlfbWFzc19nLCAzODAwLCA0MDAwKSAmIHllYXIgPCAyMDA4KQ0KYGBgDQpgc2xpY2UoKWAgdG8gcGljayByb3dzIGJhc2VkIG9uIGxvY2F0aW9uOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHNsaWNlKDIzOjI2KQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2xpY2VfaGVhZChuID0gNSkNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHNsaWNlX3NhbXBsZShwcm9wID0gMC4wMikNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHNsaWNlX21pbihmbGlwcGVyX2xlbmd0aF9tbSwgbiA9IDUpDQpgYGANCmBhcnJhbmdlKClgIHRvIGNoYW5nZSB0aGUgb3JkZXIgb2Ygcm93czoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBhcnJhbmdlKGJvZHlfbWFzc19nKSAlPiUgDQogIHNsaWNlX2hlYWQobiA9IDMpDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBhcnJhbmdlKGRlc2MoYm9keV9tYXNzX2cpKSAlPiUgDQogIHNsaWNlX2hlYWQobiA9IDMpDQpgYGANCmBzZWxlY3QoKWAgdG8gcGljayByZXNwZWN0aXZlbHkgZHJvcCBjZXJ0YWluIGNvbHVtbnM6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KDE6MykNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHNlbGVjdChzcGVjaWVzLCBpc2xhbmQsIGJpbGxfbGVuZ3RoX21tKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJzIikpDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBzZWxlY3QoZW5kc193aXRoKCJtbSIpKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KGNvbnRhaW5zKCJtbSIpKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KC1jb250YWlucygibW0iKSkNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHNlbGVjdCh3aGVyZShpcy5udW1lcmljKSkgJT4lICAgI2VxdWl2YWxlbnQgdG8gc2VsZWN0KHdoZXJlKH5pcy5udW1lcmljKC4pKSkNCiAgc2VsZWN0KHdoZXJlKH5tZWFuKC4sIG5hLnJtPVQpID4gMTAwMCkpDQpgYGANCmByZW5hbWUoKWAgdG8gY2hhbmdlIGNvbHVtbiBuYW1lczoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICByZW5hbWUoYm1pID0gYm9keV9tYXNzX2csIGdlbmRlciA9IHNleCkgJT4lIA0KICBjb2xuYW1lcygpDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICByZW5hbWVfd2l0aCguZm4gPSB0b3VwcGVyLCAuY29scyA9IGNvbnRhaW5zKCJtbSIpKSAlPiUgDQogIGNvbG5hbWVzKCkNCmBgYA0KYHJlbG9jYXRlKClgIHRvIGNoYW5nZSB0aGUgb3JkZXIgb2YgY29sdW1uczoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICByZWxvY2F0ZShzcGVjaWVzLCAuYWZ0ZXIgPSBib2R5X21hc3NfZykgJT4lDQogIHJlbG9jYXRlKHNleCwgLmJlZm9yZSA9IHNwZWNpZXMpICU+JQ0KICByZWxvY2F0ZShpc2xhbmQsIC5hZnRlciA9IGxhc3RfY29sKCkpDQpgYGANCmBtdXRhdGUoKWAgdG8gY2hhbmdlIHRoZSB2YWx1ZXMgb2YgY29sdW1ucyBhbmQvb3IgY3JlYXRlIG5ldyBjb2x1bW5zOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIG11dGF0ZSgNCiAgICBibV9rZyA9IGJvZHlfbWFzc19nIC8gMTAwMCwNCiAgICAua2VlcCA9ICJhbGwiLA0KICAgIC5hZnRlciA9IGJvZHlfbWFzc19nKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgbXV0YXRlKA0KICAgIHNleCA9IGNhc2Vfd2hlbigNCiAgICAgIHNleCA9PSAibWFsZSIgfiAxLA0KICAgICAgc2V4ID09ICJmZW1hbGUiIH4gMCksDQogICAgLmtlZXAgPSAiYWxsIikNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIG11dGF0ZSgNCiAgICBhY3Jvc3MoY29udGFpbnMoIm1tIiksIH4gLiAvIDEwMDApLA0KICAgIC5rZWVwID0gImFsbCIpDQpgYGANCmBncm91cF9ieSgpYCB0byBncm91cCByb3dzIGJhc2VkIG9uIGEgc2V0IG9mIGNvbHVtbnM6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ3JvdXBfYnkoc3BlY2llcykNCmBgYA0KYHN1bW1hcmlzZSgpYCB0byByZWR1Y2UgYSBncm91cCBpbnRvIGEgc2luZ2xlIHJvdzoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBncm91cF9ieShzcGVjaWVzKSAlPiUgI3VuaXZhcmlhdGUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ3JvdXBfYnkoc3BlY2llcywgeWVhcikgJT4lICNiaXZhcmlhdGUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ3JvdXBfYnkoc3BlY2llcykgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBhY3Jvc3MoY29udGFpbnMoIm1tIiksIH5tZWFuKC4sIG5hLnJtID0gVCksIC5uYW1lcyA9ICJ7LmNvbH1fYXZnIiksDQogICAgLmdyb3VwcyA9ICJkcm9wIikNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdyb3VwX2J5KHNwZWNpZXMpICU+JSANCiAgZ3JvdXBfYnkoeWVhciwgLmFkZCA9IFQpIA0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ3JvdXBfYnkoc3BlY2llcykgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBhY3Jvc3MoDQogICAgICBjb250YWlucygibW0iKSwNCiAgICAgIGxpc3QoYXZnID0gfm1lYW4oLiwgbmEucm0gPSBUKSwgc2QgPSB+c2QoLiwgbmEucm0gPSBUKSksDQogICAgICAubmFtZXMgPSAiey5jb2x9X3suZm59IiksDQogICAgLmdyb3VwcyA9ICJkcm9wIikNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdyb3VwX2J5KHNwZWNpZXMpICU+JSANCiAgbXV0YXRlKHN0YW5kX2JtID0gKGJvZHlfbWFzc19nIC0gbWVhbihib2R5X21hc3NfZywgbmEucm0gPSBUUlVFKSkgLyANCiAgICAgICAgICAgc2QoYm9keV9tYXNzX2csIG5hLnJtID0gVFJVRSkpDQpgYGANCmBgYHtyfQ0KYm1fYnJlYWtzIDwtIG1lYW4ocGVuZ3VpbnMkYm9keV9tYXNzX2csIG5hLnJtID0gVCkgLQ0KICAoLTM6MykgKiBzZChwZW5ndWlucyRib2R5X21hc3NfZywgbmEucm0gPSBUKQ0KDQpwZW5ndWlucyAlPiUgDQogIGdyb3VwX2J5KHNwZWNpZXMsIGJtX2NhdCA9IGN1dChib2R5X21hc3NfZywgYnJlYWtzID0gYm1fYnJlYWtzKSkgJT4lIA0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBncm91cF9ieShzcGVjaWVzLCBpc2xhbmQpICU+JSANCiAgZmlsdGVyKGZsaXBwZXJfbGVuZ3RoX21tID09IG1heChmbGlwcGVyX2xlbmd0aF9tbSwgbmEucm0gPSBUKSkNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdyb3VwX2J5KHNwZWNpZXMsIHllYXIpICU+JSANCiAgbmVzdA0KYGBgDQpgZGlzdGluY3QoKWAgdG8gc2VsZWN0IG9ubHkgdW5pcXVlIHJvd3M6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZGlzdGluY3Qoc3BlY2llcywgaXNsYW5kKQ0KYGBgDQpgcHVsbCgpYCB0byBleHRyYWN0IHNpbmdsZSBjb2x1bW5zIGFzIHZlY3RvcnM6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgcHVsbCh5ZWFyKSAjZXF1aXZhbGVudCB0byBwZW5ndWlucyR5ZWFyDQpgYGANCmBpZl9lbHNlKClgIHRvIGFwcGx5IGEgdmVjdG9yaXplZCBpZi1lbHNlLXN0YXRlbWVudA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIHNlbGVjdChzcGVjaWVzLCBpc2xhbmQsIGJvZHlfbWFzc19nKSAlPiUgDQogIG11dGF0ZShwZW5ndWluX3NpemUgPSBpZl9lbHNlKGJvZHlfbWFzc19nIDwgMzUwMCwgInRpbnkgcGVuZ3VpbiIsICJiaWcgcGVuZ3VpbiIpKQ0KYGBgDQpgbGFnKClgIGFuZCBgbGVhZCgpYCB0byBzaGlmdCBjb2x1bW4gdmFsdWVzIGJ5IGFuIG9mZnNldCBgbmA6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KHNwZWNpZXMsIGJvZHlfbWFzc19nKSAlPiUgDQogIG11dGF0ZSgNCiAgICBsYWdnZWRfYm0gPSBsYWcoYm9keV9tYXNzX2csIG4gPSAxKSwNCiAgICBsZWFkX2JtID0gbGVhZChib2R5X21hc3NfZywgbiA9IDIpKQ0KYGBgDQoNCg0KIyMgYHB1cnJyYDogRnVuY3Rpb25hbCBQcm9ncmFtbWluZyBUb29scw0KDQpgbWFwKClgIHRvIGFwcGx5IGEgZnVuY3Rpb24gdG8gZWFjaCBlbGVtZW50IG9mIGEgdmVjdG9yOg0KYGBge3J9DQp6X3RyYW5zZm9ybSA8LSBmdW5jdGlvbigueCkgew0KICBtZWFuIDwtIG1lYW4oLngsIG5hLnJtID0gVCkNCiAgc2QgPC0gc2QoLngsIG5hLnJtID0gVCkNCiAgcmV0dXJuKCAoLnggLSBtZWFuKSAvIHNkICkNCn0NCg0KcGVuZ3VpbnMgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoIm1tIikpICU+JSANCiAgbWFwKC54ID0gLiwgLmYgPSB+el90cmFuc2Zvcm0oLngpKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KGNvbnRhaW5zKCJtbSIpKSAlPiUgDQogIG1hcCgueCA9IC4sIC5mID0gZnVuY3Rpb24oLngpIHsgKC54IC0gbWVhbigueCwgbmEucm0gPSBUKSkgLyBzZCgueCwgbmEucm0gPSBUKSB9KQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgc2VsZWN0KGNvbnRhaW5zKCJtbSIpKSAlPiUgDQogIG1hcCgueCA9IC4sIC5mID0gfigueCAtIG1lYW4oLngsIG5hLnJtID0gVCkpIC8gc2QoLngsIG5hLnJtID0gVCkpDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lDQogIG1hcF9kZihjbGFzcykNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUNCiAgbWFwX2RmKH5zdW0oaXMubmEoLikpKQ0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JQ0KICBtYXBfZGYobl9kaXN0aW5jdCkNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUNCiAgZHJvcF9uYSAlPiUgDQogIGdyb3VwX2J5KHNleCkgJT4lDQogIGdyb3VwX21hcCh+c2xpY2VfbWF4KC4sIGZsaXBwZXJfbGVuZ3RoX21tLCBuID0gMSksIC5rZWVwID0gVCkNCmBgYA0KYGBge3J9DQpzcGVjaWVzIDwtIHBlbmd1aW5zICU+JSBkaXN0aW5jdChzcGVjaWVzLCB5ZWFyKSAlPiUgcHVsbChzcGVjaWVzKSAjLnggYXJndW1lbnQgZm9yIG1hcCgpDQp5ZWFycyA8LSBwZW5ndWlucyAlPiUgZGlzdGluY3Qoc3BlY2llcywgeWVhcikgJT4lIHB1bGwoeWVhcikgICAgICAjLnkgYXJndW1lbnQgZm9yIG1hcCgpDQoNCm1hcDIoDQogIC54ID0gc3BlY2llcywNCiAgLnkgPSB5ZWFycywNCiAgLmYgPSB+ew0KICAgIHBlbmd1aW5zICU+JQ0KICAgICAgZHJvcF9uYSAlPiUgDQogICAgICBmaWx0ZXIoc3BlY2llcyA9PSAueCwgeWVhciA9PSAueSkgJT4lIA0KICAgICAgZ2dwbG90KCkgKw0KICAgICAgICBnZW9tX3BvaW50KGFlcyh4ID0gYmlsbF9sZW5ndGhfbW0sIHkgPSBib2R5X21hc3NfZykpICsNCiAgICAgICAgbGFicyh0aXRsZSA9IGdsdWU6OmdsdWUoIlNjYXR0ZXIgUGxvdCBCaWxsIExlbmd0aCB2cy4gQk1JICh7Lnh9LCB7Lnl9KSIpKQ0KICAgIH0pDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBkcm9wX25hICU+JSANCiAgZ3JvdXBfYnkoc3BlY2llcywgaXNsYW5kKSAlPiUgDQogIG5lc3QgJT4lIA0KICBtdXRhdGUobGluX3JlZyA9IG1hcCgueCA9IGRhdGEsIC5mID0gfmxtKGJvZHlfbWFzc19nIH4gLiwgZGF0YSA9IC54KSkpICAlPiUgDQogIG11dGF0ZShjb2VmcyA9IG1hcChsaW5fcmVnLCB+c3VtbWFyeSgueCkgJT4lIC4kY29lZmZpY2llbnRzICU+JSBhc190aWJibGUpKSAlPiUNCiAgc2VsZWN0KC1kYXRhLCAtbGluX3JlZykgJT4lIA0KICB1bm5lc3QoY29lZnMpDQpgYGANCg0KIyMgYGdncGxvdDJgOiBDcmVhdGUgRWxlZ2FudCBEYXRhIFZpc3VhbGlzYXRpb25zIFVzaW5nIHRoZSBHcmFtbWFyIG9mIEdyYXBoaWNzDQoNCioqVW5pdmFyaWF0ZSBleGFtcGxlOioqDQoxKSBBZGQgYGRhdGFgOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChkYXRhID0gLikgI2VxdWl2YWxlbnQgdG8gZ2dwbG90KCkNCmBgYA0KMikgQWRkIGBhZXNgdGhldGljcyBtYXBwaW5nOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdCgNCiAgICBhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tKSkNCmBgYA0KMykgQWRkIGBnZW9tYDoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSkpICsNCiAgICBnZW9tX2hpc3RvZ3JhbShuYS5ybSA9IFRSVUUpDQpgYGANCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSkpICsNCiAgICBnZW9tX2JhcihuYS5ybSA9IFRSVUUpIA0KYGBgDQo0KSBBZGQgYHN0YXRgOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tKSkgKw0KICAgIGdlb21fYmFyKHN0YXQgPSAiZGVuc2l0eSIsIG5hLnJtID0gVFJVRSkgDQpgYGANClVzZSBgZ2VvbV9kZW5zaXR5KClgIGluc3RlYWQgb2YgYGdlb21fYmFyKHN0YXQgPSAiZGVuc2l0eSIpYDoNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSkpICsNCiAgICBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKQ0KYGBgDQoqKkJpdmFyaWF0ZSBleGFtcGxlOioqDQoxKSBBZGQgYGRhdGFgOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdCgpDQpgYGANCjIpIEFkZCBgYWVzYHRoZXRpY3MgbWFwcGluZzoNCmBgYHtyIHBfc3RlcF9iMiwgZXZhbD1GfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSwgeSA9IGJvZHlfbWFzc19nKSkgDQpgYGANCjMpIEFkZCBgZ2VvbWA6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmxpcHBlcl9sZW5ndGhfbW0sIHkgPSBib2R5X21hc3NfZykpICsNCiAgICBnZW9tX3BvaW50KG5hLnJtID0gVFJVRSkNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBzcGVjaWVzKSwgbmEucm0gPSBUUlVFKSANCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBiaWxsX2RlcHRoX21tKSwgbmEucm0gPSBUUlVFKSANCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV9wb2ludChjb2xvciA9ICJyZWQiLCBuYS5ybSA9IFRSVUUpIA0KYGBgDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmxpcHBlcl9sZW5ndGhfbW0sIHkgPSBib2R5X21hc3NfZykpICsNCiAgICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IHNwZWNpZXMpLCBzaXplID0gNCwgbmEucm0gPSBUUlVFKSANCmBgYA0KNSkgQWRkIGBmYWNldHNgOg0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSBzcGVjaWVzKSwgbmEucm0gPSBUUlVFKSArDQogICAgZmFjZXRfd3JhcCh+eWVhcikNCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSBzcGVjaWVzKSwgbmEucm0gPSBUUlVFKSArDQogICAgZmFjZXRfd3JhcCh+eWVhciArIGlzbGFuZCkNCmBgYA0KNikgYHNjYWxlYCBhZXN0aGV0aWNzIG1hcHBpbmc6DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmxpcHBlcl9sZW5ndGhfbW0sIHkgPSBib2R5X21hc3NfZykpICsNCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHNwZWNpZXMpLCBzaXplID0gMywgbmEucm0gPSBUUlVFKSArDQogICAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gIlNldDMiKSANCmBgYA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBzcGVjaWVzKSwgbmEucm0gPSBUUlVFKSArDQogICAgc2NhbGVfeV9sb2cxMCgpICANCmBgYA0KKipPdGhlciBleGFtcGxlczoqKg0KQm94cGxvdHMgZm9yIG51bWVyaWMgdmFyaWFibGVzDQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjb250YWlucygibW0iKSwgbmFtZXNfdG8gPSAidmFyIiwgdmFsdWVzX3RvID0gInZhbCIpICU+JSANCiAgZHJvcF9uYSAgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB2YXIsIHkgPSB2YWwpKSArDQogICAgZ2VvbV9ib3hwbG90KG5hLnJtID0gVFJVRSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yMiwgd2lkdGggPSAwLjMpIA0KYGBgDQpPcmRlcmVkIGJhciBjaGFydA0KYGBge3J9DQpwZW5ndWlucyAlPiUNCiAgZHBseXI6OmNvdW50KHNwZWNpZXMpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHByb3AgPSBuIC8gc3VtKG4pKSAlPiUNCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fY29sKGFlcyh4ID0gcHJvcCwgeSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHNwZWNpZXMsIHByb3ApKSkgKw0KICAgIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX3BlcmNlbnQoMS4pKQ0KYGBgDQpBZGphY2VudCBiYXIgY2hhcnQNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzKSkgKw0KICAgIGdlb21fYmFyKGFlcyhmaWxsID0gaXNsYW5kKSwgcG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQpTdGFja2VkIGJhciBjaGFydA0KYGBge3J9DQpwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMpKSArDQogICAgZ2VvbV9iYXIoYWVzKGZpbGwgPSBpc2xhbmQpLCBwb3NpdGlvbiA9ICJzdGFjayIpDQpgYGANCmBgYHtyIHBfc3RlcF9vNiwgZXZhbD1GfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmb3JjYXRzOjpmY3RfbHVtcChzcGVjaWVzLCBuID0gMSkpKSArDQogICAgZ2VvbV9iYXIoYWVzKGZpbGwgPSBpc2xhbmQpLCBwb3NpdGlvbiA9ICJzdGFjayIpDQpgYGANCkhpZ2gtcXVhbGl0eSBkZW5zaXR5IHBsb3QNCmBgYHtyfQ0KcCA8LSBwZW5ndWlucyAlPiUgDQogIGdncGxvdChhZXMoeCA9IGJvZHlfbWFzc19nKSkgKw0KICAgIGdlb21fZGVuc2l0eShhZXMoZmlsbCA9IHNwZWNpZXMpLCBuYS5ybSA9IFQsIGFscGhhID0gMC40KSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShmcm9tID0gMzAwMCwgdG8gPSA2MDAwLCBieSA9IDUwMCksIGxpbWl0cyA9IGMoMjAwMCwgNzAwMCkpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9jb21tYShhY2N1cmFjeSA9IDAuMDAwMSkpICsNCiAgICBsYWJzKA0KICAgICAgdGl0bGUgPSAiRGVuc2l0eSBGdW5jdGlvbiBmb3IgVGhyZWUgUGVuZ3VpbiBTcGVjaWVzIG9mIFBhbG1lciBQZW5ndWlucyIsDQogICAgICBzdWJ0aXRsZSA9ICJQYWxtZXIgQXJjaGlwZWxhZ28gKDIwMDctMjAwOSkiLA0KICAgICAgY2FwdGlvbiA9ICJEYXRhOiBodHRwczovL2dpdGh1Yi5jb20vYWxsaXNvbmhvcnN0L3BhbG1lcnBlbmd1aW5zIiwNCiAgICAgIHggPSAiQm9keSBtYXNzIFtncmFtc10iLA0KICAgICAgeSA9ICJTdGF0aXN0aWNhbCBkZW5zaXR5Ig0KICAgICkgKw0KICAgIHRoZW1lX2NsYXNzaWMoKSArICNhbHNvOiB0aGVtZV9taW5pbWFsKCkNCiAgICB0aGVtZSgNCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFjZSA9ICJpdGFsaWMiKSwNCiAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICApDQoNCnANCmBgYA0KVmlvbGluIFBsb3QNCmBgYHtyfQ0KcGVuZ3VpbnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCB5ID0gYm9keV9tYXNzX2cpKSArDQogICAgZ2VvbV92aW9saW4oYWVzKGZpbGwgPSBzcGVjaWVzKSwgbmEucm0gPSBUKSArDQogICAgdGhlbWVfY2xhc3NpYygpDQpgYGANCkxpbmVzIG9mIEJlc3QgRml0DQpgYGB7cn0NCnBlbmd1aW5zICU+JSANCiAgZHJvcF9uYSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZsaXBwZXJfbGVuZ3RoX21tLA0KICAgICAgICAgICAgIHkgPSBib2R5X21hc3NfZykpICsNCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHNwZWNpZXMpKSArDQogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUKQ0KYGBgDQoNCg0KIyNgcGxvdGx5YDogSW50ZXJhY3RpdmUgV2ViIEdyYXBoaWNzDQpgYGB7ciwgb3V0LmhlaWdodD0nNzAlJywgb3V0LndpZHRoPScxMDAlJ30NCnBsb3RseTo6Z2dwbG90bHkocCkNCmBgYA0KDQoNCiMjYHBhdGNod29ya2A6IFRoZSBDb21wb3NlciBvZiBQbG90cw0KDQpgYGB7ciwgb3V0LndpZHRoPSc3NSUnLCBvdXQuaGVpZ2h0PSc3NSUnLCBmaWcucmV0aW5hPTMsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmxpYnJhcnkocGF0Y2h3b3JrKQ0KcCArIHAgKyBwDQpgYGANCmBgYHtyLCBvdXQud2lkdGg9Jzc1JScsIG91dC5oZWlnaHQ9Jzc1JScsIGZpZy5yZXRpbmE9MywgZmlnLmFsaWduPSdjZW50ZXInfQ0KbGlicmFyeShwYXRjaHdvcmspDQpwICsgKHAgLyBwKQ0KYGBgDQo=